基于Swup的Kirby站点AJAX加载后Load More按钮事件无法触发
原生JS实现等价于jQuery.on()的委托事件,适配Swup无刷新导航
核心问题
Swup做无刷新导航时会替换指定容器内的DOM节点,你初始化时直接绑在.load-more按钮上的点击事件,会跟着旧按钮节点一起被销毁,自然就失效了。之前用jQuery绑在document上的事件能一直生效,本质是靠事件冒泡委托——不需要每次DOM重载就重新绑事件,原生JS完全可以复刻这个能力,根本不用引jQuery。
具体改法
- 别再把事件直接绑在按钮上了,把事件绑定在永远不会被Swup替换的稳定节点(比如
document,和你之前jQuery绑的位置一模一样),点击触发时再判断目标是不是匹配.load-more,符合条件才执行加载逻辑 - 修掉原代码里硬编码
news.json/page:2的bug,你已经声明了page变量存当前页码,结果硬写死第二页,翻第三页的时候还会重复拉第二页的内容 - 加空值判断,不然Swup切到没有博客板块的页面时,代码找不到
.articles、.load-more节点直接抛错中断
改完的可运行代码
// 事件直接绑在全局document上,永远不会随Swup换DOM消失 document.addEventListener('click', async (e) => { // 兼容按钮内部嵌套图标、文字span的场景,只要点的是按钮内部就命中 const targetBtn = e.target.closest('.load-more'); if (!targetBtn) return; // 每次触发时再从当前DOM取节点,不缓存旧的废弃节点 const articleBox = document.querySelector('.articles'); if (!articleBox) return; const currentPage = parseInt(articleBox.getAttribute('data-page')); const nextPage = currentPage + 1; try { const response = await fetch(`news.json/page:${nextPage}`); const { html, more } = await response.json(); targetBtn.hidden = !more; articleBox.innerHTML += html; // 同步更新DOM上的页码标记,给下一次加载留状态 articleBox.setAttribute('data-page', nextPage); } catch (error) { console.log('Fetch error: ', error); } })
配合Swup的注意点
- 完全不需要在Swup的内容重载回调里重新跑初始化逻辑,事件已经绑在document上了,不管Swup加载哪个页面,只要页面里出现
.load-more按钮,点了就有反应 - 不用缓存全局的
.articles、.load-more节点,这些节点会随Swup切页被替换,初始化时缓存的全是旧页面的废弃节点,很容易出现操作错DOM、空引用的问题
内容的提问来源于stack exchange,提问作者Robert Farrelly
相关产品推荐
相关产品推荐

