You need to enable JavaScript to run this app. 基于Swup的Kirby站点AJAX加载后Load More按钮事件无法触发
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 04:15:06