Ajax函数中jQuery对象转原生JS方法及DOMParser异常排查
问题:原生JS替换jQuery解析HTML实现Colcade瀑布流加载时出现重复/缺失问题
我用原生JS实现了Ajax滚动加载文章的功能,搭配Colcade JS做瀑布流布局。现在要把代码里的jQuery语句const posts = $(data);换成原生JS,试了用DOMParser解析HTML,但出现部分文章重复、部分缺失的情况,求解决办法。
原JS代码
const grid = document.querySelector(".js-grid"); if (grid) { // Colcade JS var colc = new Colcade(grid, { columns: '.js-grid-col', items: '.js-grid-article' }); // Ajax const current_post_type = grid.dataset.currentPostType; const posts_myajax = grid.dataset.postsMyajax; let current_page_myajax = grid.dataset.currentPageMyajax; const max_page_myajax = grid.dataset.maxPageMyajax; const ajax_url = grid.dataset.ajaxUrl; const current_action = grid.dataset.action; var throttleTimer; const throttle = (callback, time) => { if (throttleTimer) return; throttleTimer = true; setTimeout(() => { callback(); throttleTimer = false; }, time); }; const handleInfiniteScroll = () => { throttle(() => { const endOfPage = window.innerHeight + window.pageYOffset >= document.body.offsetHeight; if (endOfPage) { const data = new FormData(); data.append( 'action', current_action ); data.append( 'archive_post_type', current_post_type ); data.append( 'query', posts_myajax ); data.append( 'page', current_page_myajax ); fetch(ajax_url, { method: "POST", body: data }) .then((response) => response.text()) .then((data) => { if (data) { const posts = $(data); colc.append(posts); current_page_myajax++; } }); } if (current_page_myajax == max_page_myajax) { removeInfiniteScroll(); } }, 1000); }; const removeInfiniteScroll = () => { window.removeEventListener("scroll", handleInfiniteScroll); }; window.addEventListener("scroll", handleInfiniteScroll); }
尝试的DOMParser代码
const parser = new DOMParser(); const doc = parser.parseFromString(data, "text/html"); let posts = doc.querySelectorAll('.js-grid-article') if (posts) { colc.append(posts); }
解决方案
问题原因
querySelectorAll返回的是NodeList对象,Colcade的append方法对NodeList兼容性不如数组或jQuery对象,易导致元素处理异常。- DOMParser会自动补全
html、body等外层标签,如果后端返回的HTML本身包含这类结构,会导致选择器选中错误元素。 - 未对空内容或无效响应做判断,可能触发无意义的追加操作。
修改后的代码
.then((data) => { // 过滤空内容或纯空格的响应 if (!data.trim()) return; const parser = new DOMParser(); const doc = parser.parseFromString(data, "text/html"); // 直接从body节点内选取目标元素,避免外层结构干扰 const postNodes = doc.body.querySelectorAll('.js-grid-article'); // 将NodeList转换为数组,适配Colcade的append方法 const posts = Array.from(postNodes); if (posts.length > 0) { colc.append(posts); current_page_myajax++; } });
额外排查点
- 检查后端接口分页参数是否生效:确认
current_page_myajax传递后,后端返回对应页码内容,而非重复返回同一页。 - 验证节流函数是否正常工作:如果节流失效,可能导致同一页被多次请求,出现重复内容。
- 确认Colcade版本:部分旧版本对非jQuery对象的元素集合支持不佳,升级到最新稳定版可避免这类问题。
内容的提问来源于stack exchange,提问作者Mathieu Préaud
相关产品推荐
相关产品推荐

