将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
相关产品推荐
相关产品推荐

