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

使用Vanilla JavaScript实现移动端无限滚动触发失效问题求解

问题根因

  • 移动端浏览器的地址栏、底部工具栏会动态收缩/展开,document.documentElement.clientHeight计算的视口高度会随之波动,原代码中scrollTop + clientHeight >= scrollHeight的严格触底判断很难命中
  • 部分移动端浏览器的滚动橡皮筋效果会导致触底时scrollTop取值出现瞬时偏差,无法满足判断条件
  • 少数浏览器中滚动距离需要从document.body.scrollTop取值,仅读取document.documentElement.scrollTop可能拿到0值

修复方案

方案1:修改原有滚动监听逻辑(低成本适配)

  1. 给触底判断增加缓冲阈值,不需要完全触底就提前触发请求,同时兼容不同浏览器的scrollTop取值
  2. 增加加载状态锁,避免滚动过程中重复触发接口请求
    修改后代码如下:
// 全局定义加载状态锁,避免重复请求
let isLoading = false;

window.addEventListener("scroll", () => {
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  const { scrollHeight, clientHeight } = document.documentElement;
  // 100px为缓冲阈值,可根据业务需求调整大小
  if (scrollTop + clientHeight >= scrollHeight - 100 && !isLoading) {
    isLoading = true;
    showLoading();
  }
});

// 原有请求逻辑中新增锁重置的逻辑
function showLoading() {
  // 调用TMDB API拉取数据的原有逻辑
  fetch(/* 你的TMDB请求地址 */)
    .then(res => res.json())
    .then(data => {
      // 原有数据渲染逻辑
      // ...
    })
    .finally(() => {
      // 请求结束后重置加载状态,允许下次触发
      isLoading = false;
    })
}

方案2:使用Intersection Observer实现(性能更优、兼容性好)

如果不想手动处理滚动计算的各种兼容问题,可以用原生Intersection Observer API实现,性能远高于高频scroll事件监听,且天然适配各端视口差异:

  1. 首先在列表末尾新增一个触发加载的占位元素:
<ul id="movieList">
  <!-- 原有电影列表内容 -->
</ul>
<!-- 加载触发锚点 -->
<div id="loadTrigger"></div>
  1. 替换原有scroll监听逻辑为Observer监听:
let isLoading = false;
const loadTrigger = document.querySelector('#loadTrigger');

const observer = new IntersectionObserver((entries) => {
  // 锚点元素进入视口且不在加载状态时触发请求
  if (entries[0].isIntersecting && !isLoading) {
    isLoading = true;
    showLoading();
  }
});
// 监听锚点元素
observer.observe(loadTrigger);

// showLoading函数的逻辑和方案1中一致,请求结束后重置isLoading即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:54:08