You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将jQuery代码转原生JS遇阻:AJAX、$.extend及$.merge转换难题

问题描述

我正在把旧的jQuery脚本转为原生JS,大部分功能已经完成,但卡在以下几个点:

  • 初始函数调用的原生转换(比如$(document).ready)
  • $.merge和$.extend方法的替代实现
  • $.ajax调用转为原生JS版本

原jQuery代码

(function($){
    $(document).ready(function() {
      
      $.ajax({
        url: "https://api.flickr.com/services/rest/?method=flickr.galleries.getPhotos&api_key=*PRIVATE*c&gallery_id=72157720949295872&per_page=10&format=json&nojsoncallback=1",
        type: "GET",
        success: function(data) {
          console.log("api successfully called")
    
          let path = data.photos.photo
          for (let i = 0; i < path.length; i++) {
            let obj = path[i];
            let farm_id = data.photos.photo[i].farm
            let server_id = data.photos.photo[i].server
            let photo_id = data.photos.photo[i].id
            let secret = data.photos.photo[i].secret
    
            let pic_url = "https://farm" + farm_id + ".staticflickr.com/" + server_id + "/" + photo_id + "_" + secret;
            let pic_url_m = pic_url + "_m.jpg";
            let pic_img = ('<img src=\'' + pic_url_m + '\' alt = \"pic\" />');
          
            $('#photo-list').append(pic_img);
            $('#photo-list img').addClass("paginate");
            
          }
    
          $('.pagination').customPaginate({
                itemsToPaginate: ".paginate"
            });
    
          $('.paginate').click(function() {
            let src = $(this).attr('src');
            let src_l = src.slice(0, -6) + "_c.jpg";
            $('#frame img').attr('src', src_l);
           $('#frame img').fadeIn();
            $('#overlay').fadeIn();
    
            $('#overlay').click(function() {
              $(this).fadeOut();
              $('#frame img').fadeOut();
              $('#frame img').removeAttr('src');
              });
            });
          }
        });
      });
    
    $.fn.customPaginate = function(options)
        {
          let paginationContainer = this;
               
          let defaults = {
              itemsPerPage : 10
               };
            
          let settings = {};
          
          $.extend(settings, defaults, options);
          
          let itemsPerPage = settings.itemsPerPage;
           
          let itemsToPaginate = $(settings.itemsToPaginate);
    
          let numberOfItems = Math.ceil((itemsToPaginate.length / itemsPerPage));
              
          $("<ul></ul>").prependTo(paginationContainer);
               
          for(let index = 0; index < numberOfItems; index++)
          {
            paginationContainer.find('ul').append('<li>'+ (index+1) + '</li>');
          }
    
          itemsToPaginate.filter(":gt(" + (itemsPerPage - 1)  + ")").hide();
               
          paginationContainer.find("ul li").first().addClass(settings.activeClass).end().on('click', function(){
             
          let $this = $(this);
                 
          $this.addClass(settings.activeClass);
          $this.siblings().removeClass(settings.activeClass);
               
          let pageNumber = $this.text();
                   
          let itemsToHide = itemsToPaginate.filter(":lt(" + ((pageNumber-1) * itemsPerPage)  + ")");
    
          $.merge(itemsToHide, itemsToPaginate.filter(":gt(" + ((pageNumber * itemsPerPage) - 1)  + ")"));
                    
          let itemsToShow = itemsToPaginate.not(itemsToHide);
    
          $("html,body").animate({scrollTop:"0px"}, function(){
              itemsToHide.hide();
              itemsToShow.show();
            });
        });
      }
    
    }(jQuery));

待完成的原生JS代码

(function($){

    document.querySelector(document).ready(function() {
      
      $.ajax({   //need to convert this to JS
        url: "https://api.flickr.com/services/rest/?method=flickr.galleries.getPhotos&api_key=*PRIVATE*c&gallery_id=72157720949295872&per_page=10&format=json&nojsoncallback=1",
        type: "GET",
        success: function(data) {
          console.log("api successfully called")
                        // ....truncated
          }
        });
      });
    
      $.fn.customPaginate = function()
        {
          let paginationContainer = this;
               
          let defaults = {
              itemsPerPage : 10
               };
            
          let settings = {};
          
          //need to convert this extend to JS
          $.extend(settings, defaults, options);
          
          let itemsPerPage = settings.itemsPerPage;
           
         // ....truncated
               
          let pageNumber = qS.text();
                   
          let itemsToHide = itemsToPaginate.filter(":lt(" + ((pageNumber-1) * itemsPerPage)  + ")");
    
          //need to convert this extend to JS
          $.merge(itemsToHide, itemsToPaginate.filter(":gt(" + ((pageNumber * itemsPerPage) - 1)  + ")"));
                    
        });
      }
    }(jQuery));

解决方案

1. 替换$.ajax:使用Fetch API

原生JS用fetch()替代jQuery的$.ajax,通过Promise处理异步请求:

fetch('https://api.flickr.com/services/rest/?method=flickr.galleries.getPhotos&api_key=*PRIVATE*c&gallery_id=72157720949295872&per_page=10&format=json&nojsoncallback=1', {
  method: 'GET'
})
.then(response => {
  if (!response.ok) throw new Error('请求失败');
  return response.json();
})
.then(data => {
  console.log("api successfully called");
  // 后续图片渲染等逻辑
})
.catch(error => console.error('请求出错:', error));

2. 替换$.extend:对象合并

$.extend用于合并对象属性,原生用展开运算符或Object.assign()实现:

// 方式1:展开运算符(推荐,更直观)
let settings = {...defaults, ...options};

// 方式2:Object.assign
let settings = Object.assign({}, defaults, options);

3. 替换$.merge:数组合并

$.merge用于合并两个数组,原生用展开运算符或Array.push.apply():

// 方式1:展开运算符合并数组
let itemsToHide = [
  ...Array.from(itemsToPaginate).slice(0, (pageNumber-1)*itemsPerPage),
  ...Array.from(itemsToPaginate).slice(pageNumber*itemsPerPage)
];

// 方式2:push.apply合并到已有数组
itemsToHide.push(...Array.from(itemsToPaginate).slice(pageNumber*itemsPerPage));

4. 其他jQuery特性的原生转换

  • $(document).ready:替换为DOMContentLoaded事件
    document.addEventListener('DOMContentLoaded', function() {
      // 页面加载完成后的逻辑
    });
    
  • 元素选择与操作:
    • $('#photo-list').append(pic_img) → document.getElementById('photo-list').insertAdjacentHTML('beforeend', pic_img)
    • $(selector).addClass('paginate') → element.classList.add('paginate')
    • $(selector).click(fn) → element.addEventListener('click', fn)
    • $(selector).attr('src', val) → element.setAttribute('src', val)
  • fadeIn/fadeOut动画:用CSS过渡或自定义函数实现
    function fadeIn(element) {
      element.style.opacity = 0;
      element.style.display = 'block';
      let opacity = 0;
      const timer = setInterval(() => {
        opacity += 0.1;
        element.style.opacity = opacity;
        if (opacity >= 1) clearInterval(timer);
      }, 30);
    }
    
    function fadeOut(element) {
      let opacity = 1;
      const timer = setInterval(() => {
        opacity -= 0.1;
        element.style.opacity = opacity;
        if (opacity <= 0) {
          clearInterval(timer);
          element.style.display = 'none';
        }
      }, 30);
    }
    
  • :gt/:lt筛选:将NodeList转为数组后用slice()处理
    // 替代:gt(n),获取索引大于n的元素
    const gtItems = Array.from(itemsToPaginate).slice(n+1);
    // 替代:lt(n),获取索引小于n的元素
    const ltItems = Array.from(itemsToPaginate).slice(0, n);
    

内容的提问来源于stack exchange,提问作者E_Bloomquist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 11:57:09