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

自定义jQuery无限滚动:请求发送后启停scroll事件及防抖异常解决

解决jQuery无限滚动的「Illegal invocation」错误与事件开关问题

嘿,我来帮你搞定这个问题!你遇到的「Illegal invocation」错误主要是因为防抖函数没有正确传递事件上下文(this指向)和参数,再加上滚动事件的开关逻辑没做好,咱们一步步来修复:

1. 先修复防抖函数的上下文传递问题

你的防抖函数大概率没有处理this和参数的传递,导致scroller函数里的$(this)指向错误,触发非法调用。先换一个能正确传递上下文和参数的标准防抖函数:

// 标准防抖函数,支持传递this和参数
function debounce(func, wait) {
  let timeoutId;
  return function(...args) {
    const context = this;
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      func.apply(context, args); // 把当前上下文和参数传给原函数
    }, wait);
  };
}

2. 调整滚动逻辑,添加请求锁防止重复触发

为了避免滚动时重复发送请求,我们需要一个锁变量,在请求发送期间禁用滚动监听,请求完成后再恢复。同时把$(this)换成$(document),避免上下文问题:

// 全局锁:标记是否正在发送请求
let isLoading = false;
// 保存分页参数(可以直接用你原有的page变量,这里统一管理)
let page = $('#pageNumber').data('page') || 1;

function scroller(lang, type, genre, sort) {
  // 如果正在加载,直接返回
  if (isLoading) return;

  const scrollTop = $(document).scrollTop();
  const pagesTop = $('#pages').position().top;
  // 触发加载的条件
  if (scrollTop * 2 >= pagesTop) {
    // 开启加载锁,禁用滚动触发
    isLoading = true;
    // 解绑滚动事件(可选,也可以靠isLoading锁控制)
    $(document).off('scroll', debouncedScroller);

    $.post('<?= (new UrlLibry)->SetUrl('bookshop', 'jajax', 'page'); ?>', {
      lang: lang,
      type: type,
      genre: genre,
      sort: sort,
      pages: page
    }, function(data) {
      $('#loadmore').append(data);
      page++;
      $('#pageNumber').data('page', page);
    })
    .always(function() {
      // 请求完成(成功/失败)后,关闭加载锁,重新绑定滚动事件
      isLoading = false;
      $(document).on('scroll', debouncedScroller);
    });
  }
}

// 创建防抖后的滚动处理函数
const debouncedScroller = debounce(scroller, 50);
// 初始绑定滚动事件
$(document).on('scroll', () => {
  // 这里传递scroller需要的参数(lang, type等,根据你的实际变量传入)
  debouncedScroller(lang, type, genre, sort);
});

3. 手动开关滚动事件的方法

如果你需要在其他地方手动开启/关闭滚动事件,直接用保存的debouncedScroller变量即可:

// 关闭滚动事件
$(document).off('scroll', debouncedScroller);

// 重新开启滚动事件
$(document).on('scroll', () => {
  debouncedScroller(lang, type, genre, sort);
});

关键说明

  • 防抖函数的apply调用:确保原scroller函数能拿到正确的上下文,同时传递所需的参数,我们换成$(document)也让逻辑更稳妥。
  • 加载锁isLoading:避免在请求未完成时重复触发滚动加载,比单纯解绑事件更灵活,也能减少事件绑定/解绑的开销。
  • always回调:不管请求成功还是失败,都要恢复滚动监听,避免页面卡住无法继续加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:25:52