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

WordPress+Timber+Twig中jQuery Ajax+Waypoints滚动加载图片异常排查

解决WordPress+Timber+Twig中Waypoint无限滚动的元素绑定与分批加载问题

看起来你遇到的核心问题有两个:Waypoint初始化时找不到目标DOM元素,以及无法正确实现每次加载10张图片的分批触发逻辑。咱们一步步拆解问题并修复:

问题诊断

  1. DOM结构损坏:你在拼接图片HTML时,<img>标签的src属性遗漏了闭合引号,导致生成的DOM结构异常,Waypoint无法识别目标容器。
  2. 索引不匹配:初始page值的计算逻辑有问题——如果画廊图片数量少于9张,你直接把page设为10,这显然对应不上实际存在的元素ID。
  3. Waypoint回调逻辑错误:创建新Waypoint时,你直接写handler: ajax_call(page, ppp),这会立即执行请求而非作为滚动触发的回调;同时没有处理边界情况(比如最后一批不足10张的场景)。

分步解决方案

1. 修复HTML拼接的语法错误

先修正add_posts函数里的标签闭合问题,确保生成的DOM结构完全正确:

function add_posts(img_link, key) {
  $(".gallery-ajax").append(
    '<div class="img-container" id="img-container' + key + '">' +
    '<a data-fancybox="gallery" id="image' + key + '" href="' + img_link + '">' +
    '<img src="' + img_link + '">' + // 补全src属性的闭合引号
    '</a>' +
    '</div>'
  );
}

2. 确保DOM加载完成后再绑定Waypoint

即使使用了jQuery(document).ready,也要先检查目标元素是否存在再初始化Waypoint,避免因Twig渲染延迟导致的元素找不到问题。

3. 修正Waypoint的回调与绑定逻辑

  • 用匿名函数包裹回调,避免请求立即执行
  • 每次加载完成后,更新page为最后一个新元素的索引,再绑定新的Waypoint
  • 添加边界判断:当没有更多图片时,销毁旧Waypoint避免无效触发

完整修正后的代码

jQuery(document).ready(function ($) {
  var ajaxUrl = "{{ fn('admin_url', 'admin-ajax.php') }}";

  // 修复HTML拼接错误,确保DOM结构正确
  function add_posts(img_link, key) {
    $(".gallery-ajax").append(
      '<div class="img-container" id="img-container' + key + '">' +
      '<a data-fancybox="gallery" id="image' + key + '" href="' + img_link + '">' +
      '<img src="' + img_link + '">' +
      '</a>' +
      '</div>'
    );
  }

  // 封装AJAX请求,返回Promise方便后续链式调用
  function ajax_call(page, ppp) {
    return $.post(ajaxUrl, {
      action: "more_post_ajax",
      page: page,
      ppp: ppp
    });
  }

  // 初始化参数:用Twig变量提前计算画廊长度,避免重复渲染
  {% set gallery_total = post.gallery | length %}
  var page = {% if gallery_total >=9 %}8{% else %}gallery_total -1{% endif %}; // 对应最后一个已加载元素的索引
  var ppp = 10;
  var totalImages = {{ gallery_total }};
  var currentWaypoint = null;

  // 封装Waypoint初始化逻辑,避免重复代码
  function bindWaypoint(targetIndex) {
    var targetElement = document.getElementById("img-container" + targetIndex);
    if (!targetElement) {
      console.warn("目标元素不存在,无法绑定Waypoint: img-container" + targetIndex);
      return;
    }

    // 销毁旧Waypoint,避免重复触发请求
    if (currentWaypoint) {
      currentWaypoint.destroy();
    }

    currentWaypoint = new Waypoint({
      element: targetElement,
      handler: function () {
        console.log("触发加载,当前最后一张图片索引: " + page);
        var nextPageStart = page + 1;
        
        // 只有还有图片未加载时才发起请求
        if (nextPageStart >= totalImages) {
          currentWaypoint.destroy();
          return;
        }

        ajax_call(nextPageStart, ppp)
          .success(function (data) {
            if (data.length === 0) {
              console.log("没有更多图片了");
              currentWaypoint.destroy();
              return;
            }

            // 渲染新图片并更新最后一个元素的索引
            $.each(data, function (key, val) {
              add_posts(val.img_link, val.skaitliukas);
              page = val.skaitliukas;
            });

            // 刷新Waypoint识别新DOM元素,绑定新的触发点
            Waypoint.refreshAll();
            bindWaypoint(page);
          })
          .error(function () {
            console.error("图片加载失败,请稍后重试");
          });
      },
      offset: 'bottom-in-view'
    });
  }

  // 初始化第一个Waypoint(只有当还有未加载图片时才执行)
  if (page + 1 < totalImages) {
    bindWaypoint(page);
  }
});

更简便的替代方案:原生滚动监听

如果觉得Waypoint库过于繁琐,可以用原生滚动事件实现相同效果,无需额外依赖:

jQuery(document).ready(function ($) {
  var ajaxUrl = "{{ fn('admin_url', 'admin-ajax.php') }}";
  {% set gallery_total = post.gallery | length %}
  var page = {% if gallery_total >=9 %}8{% else %}gallery_total -1{% endif %};
  var ppp = 10;
  var totalImages = {{ gallery_total }};
  var isLoading = false; // 防止滚动时重复发起请求

  function add_posts(img_link, key) {
    $(".gallery-ajax").append(
      '<div class="img-container" id="img-container' + key + '">' +
      '<a data-fancybox="gallery" id="image' + key + '" href="' + img_link + '">' +
      '<img src="' + img_link + '">' +
      '</a>' +
      '</div>'
    );
  }

  // 监听滚动事件
  $(window).scroll(function () {
    if (isLoading || page + 1 >= totalImages) return;

    // 判断是否滚动到页面底部附近(距离底部200px时触发)
    if ($(window).scrollTop() + $(window).height() >= $(document).height() - 200) {
      isLoading = true;
      $.post(ajaxUrl, {
        action: "more_post_ajax",
        page: page + 1,
        ppp: ppp
      }).success(function (data) {
        if (data.length === 0) {
          $(window).off('scroll'); // 移除监听,避免无效触发
          isLoading = false;
          return;
        }

        $.each(data, function (key, val) {
          add_posts(val.img_link, val.skaitliukas);
          page = val.skaitliukas;
        });
        isLoading = false;
      }).error(function () {
        isLoading = false;
        console.error("加载失败,请稍后重试");
      });
    }
  });
});

这个方案更轻量,不需要引入Waypoint库,适合简单的无限滚动场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:49:04