移动端快速滑动时如何检测滚动溢出结束状态?
移动端惯性滚动时无法检测滚动边界的解决方案
问题背景
在移动端,当用户快速拉动可滚动内容使其进入惯性滚动状态后,ontouchmove事件不会触发,导致无法实时检测滚动位置。比如需要在滚动到左侧尽头时隐藏“更多内容”横幅,仅依赖ontouchmove的方案只能在用户主动触摸滑动时生效,惯性滚动到尽头时完全无法触发检测逻辑。
原实现代码
JavaScript
function onTouchMove() { const node = document.getElementById("scroll-container"); const overflownOnRight = Math.ceil(node.scrollLeft + node.offsetWidth) < node.scrollWidth; if (!overflownOnRight) { document.getElementById("info-banner").style.display = "none"; } else { document.getElementById("info-banner").style.display = "block"; } }
CSS
.scroll-container { margin-top: 100px; width: 100%; height: 40px; overflow-y: auto; &::-webkit-scrollbar { height: 0; width: 0; display: none; } } .reference-point { height: 30px; width: 100%; border: 5px dotted pink; } .scrollable { width: 1200px; height: 100%; background: blue; display: flex; }
HTML
<div id="scroll-container" ontouchmove="onTouchMove(event)" class="scroll-container shadowed"> <div class="scrollable"> <div class="reference-point"> </div> </div> </div> <div id="info-banner"> Scroll Right For More Content </div>
解决方案核心思路
放弃ontouchmove,改用scroll事件——该事件会在所有滚动场景下触发,包括用户主动滑动和惯性滚动阶段,能实时捕获滚动位置变化。同时可加入防抖优化,减少频繁DOM操作带来的性能损耗。
修改后的实现代码
优化后的JavaScript
// 核心检测逻辑 function checkScrollPosition() { const scrollContainer = document.getElementById("scroll-container"); const infoBanner = document.getElementById("info-banner"); // 判断是否还有右侧可滚动内容 const hasMoreContent = Math.ceil(scrollContainer.scrollLeft + scrollContainer.offsetWidth) < scrollContainer.scrollWidth; infoBanner.style.display = hasMoreContent ? "block" : "none"; } // 防抖函数:减少scroll事件触发频率,优化性能 function debounce(func, delay = 80) { let timerId; return function() { clearTimeout(timerId); timerId = setTimeout(() => func.apply(this, arguments), delay); }; } // 绑定事件 document.addEventListener("DOMContentLoaded", () => { const scrollContainer = document.getElementById("scroll-container"); // 绑定防抖后的scroll事件 scrollContainer.addEventListener("scroll", debounce(checkScrollPosition)); // 页面加载完成后初始化一次状态 checkScrollPosition(); });
修改后的HTML
移除内联的ontouchmove属性,改为通过JS绑定事件:
<div id="scroll-container" class="scroll-container shadowed"> <div class="scrollable"> <div class="reference-point"> </div> </div> </div> <div id="info-banner"> Scroll Right For More Content </div>
CSS保持不变
原CSS无需修改,可继续使用。
方案说明
scroll事件的优势:覆盖所有滚动场景,无论是主动触摸滑动还是惯性滚动,都能实时获取scrollLeft值,确保边界检测逻辑全程生效。- 防抖优化:滚动过程中
scroll事件会高频触发,防抖函数能将多次检测合并为一次,避免频繁操作DOM导致的性能问题。 - 初始化检测:页面加载完成后主动调用一次检测逻辑,确保初始状态下横幅的显示/隐藏符合当前滚动位置。
内容的提问来源于stack exchange,提问作者Green Mint
相关产品推荐
相关产品推荐

