如何避免过度滚动时AJAX请求重复加载相同结果?
滚动加载重复请求问题修复方案
核心问题
快速滚动到底部时,原代码的事件防抖和请求锁机制不完善,导致多次触发带着旧lastId的AJAX请求,重复加载相同内容。
修复后的完整代码
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script type="text/javascript"> // 请求锁:标记是否正在加载数据,防止重复请求 let isLoading = false; window.onscroll = function() { // 如果正在加载,直接跳过当前滚动触发的逻辑 if (isLoading) return; const scrollReachBottom = window.innerHeight + Math.ceil(window.pageYOffset) >= document.body.offsetHeight; if (scrollReachBottom) { // 立即上锁,阻止后续滚动事件触发请求 isLoading = true; const lastId = $(".postid:last").attr("id"); const elem = document.getElementById("ele"); getMoreData(lastId); elem.scrollIntoView(); } } function getMoreData(lastId) { $.ajax({ url: 'load_more.php?lastId=' + lastId, type: "get", beforeSend: function () { $('.ajax-loader').show(); }, success: function (data) { // 先追加新内容到页面,保证页面高度及时更新 $("#post-list").append(data); // 延迟隐藏加载器,保留加载动画的视觉反馈 setTimeout(function() { $('.ajax-loader').hide(); }, 1000); // 请求完成后,重新绑定滚动事件,解锁允许下次加载 $(window).on("scroll", window.onscroll); isLoading = false; }, // 处理请求失败的情况,避免锁一直处于开启状态 error: function() { $('.ajax-loader').hide(); $(window).on("scroll", window.onscroll); isLoading = false; } }); } </script>
关键修改说明
- 新增加载锁
isLoading:滚动事件触发时先检查是否正在加载,直接拦截重复请求,从根源上避免带着旧lastId的请求被重复发送。 - 移除多余的
setTimeout:原代码里的0延迟定时器会捕获当时的旧lastId,且延迟请求执行,去掉后能直接获取当前最新的DOM节点ID。 - 调整DOM更新时机:成功回调里先追加新内容再隐藏加载器,确保页面高度及时更新,后续滚动判断不会出错。
- 完善请求收尾逻辑:无论请求成功还是失败,都要重新绑定滚动事件并解锁,防止页面后续无法触发加载。
- 优化滚动事件解绑逻辑:原代码进入请求就解绑滚动事件,现在改为请求完成后再重新绑定,配合加载锁,逻辑更可靠。
内容的提问来源于stack exchange,提问作者Geert
相关产品推荐
相关产品推荐

