滚动未达页面底部时加载内容,JavaScript代码崩溃求助
解决滚动加载时提前触发导致一次性加载全部内容的问题
嘿,这个问题我之前也踩过坑!核心原因就是AJAX请求是异步的:当你触发加载后,页面内容还没来得及更新($(document).height()没变),但滚动事件还在持续触发,currentScroll >= goal的条件会一直成立,于是就会不断调用ajaxGet,直到所有内容加载完。而你尝试的while循环会导致同步阻塞,直接卡死浏览器,肯定不行。
下面给你一个靠谱的解决方案,核心思路是加一个「加载锁」,确保同一时间只有一个AJAX请求在运行,并且在请求完成后再重新检查滚动条件:
步骤分解
- 新增一个全局变量
isLoading来标记当前是否正在加载内容 - 在滚动事件触发时,先检查
isLoading,如果正在加载就直接跳过 - 在AJAX的
success和error回调中,把isLoading重置为false,并主动重新检查滚动条件(避免用户在加载过程中已经滚动到新的目标位置)
修改后的完整代码
// 新增加载锁,初始为未加载状态 let isLoading = false; $(window).scroll(function() { var currentScroll = $(window).scrollTop(); var goal = $(document).height() - $(window).height(); // 页面底部位置 goal = goal * 0.5; // 提前至页面一半位置加载内容 // 检查是否所有内容已加载,运行正常! var result_count = document.getElementsByClassName('yacht-count')[0].innerHTML; total_results_to_show = group_of_villas_showed * results_to_show; if (result_count / total_results_to_show <= 1) { goal = currentScroll * 2; console.log("Finish"); } // 关键:如果正在加载,直接返回,避免重复触发 if (isLoading) { return; } // 检查当前滚动位置是否大于设定的目标位置 if (currentScroll >= goal) { console.log("start loading villas"); // 标记为正在加载 isLoading = true; ajaxGet(guests_value, destinations_value, sort_by, current_page); current_page++; group_of_villas_showed += 1; console.log("loading villas"); } }); ajaxGet = (guests_value, destinations_value, sort_by, page, replace = false) => { $.ajax({ type: 'GET', url: ajax_url, data: { guests: guests_value, destination: destinations_value, sort_by: sort_by, page: page, }, dataType: 'json', beforeSend: function() { $('#loading-image').removeClass('hide'); $('.yachts-search-page').addClass('loading-more'); }, success: function(data) { $('.yachts-search-page').removeClass('loading-more'); $('#loading-image').addClass('hide'); if (replace) { $('body .load-more-wrapper').show(); $('body .yachts-inner').html(data.content); current_page = 1; } else { $('body .yachts-inner').append(data.content); } $('body .yacht-count').text(data.yacht_count); newQueryString(guests_value, destinations_value, sort_by, page); // 加载完成,解锁 isLoading = false; // 主动触发一次滚动事件,检查是否需要继续加载 $(window).trigger('scroll'); }, error: function(data) { // 即使加载失败,也要解锁,避免永远无法再次加载 isLoading = false; console.log('加载失败,请重试'); } }); }
关键修改点说明
- 加载锁
isLoading:确保同一时间只有一个AJAX请求在执行,彻底解决重复触发的问题 - AJAX回调解锁:不管成功还是失败,都要把
isLoading设为false,防止页面陷入无法加载的状态 - 主动触发滚动事件:在
success回调中触发$(window).trigger('scroll'),这样当新内容加载完成后,会自动检查当前滚动位置是否满足新的目标条件,如果满足就继续加载下一页
这个方案既解决了一次性加载全部内容的问题,又能保证在用户滚动过程中流畅地分批加载内容,你可以直接拿去测试~
内容的提问来源于stack exchange,提问作者george
相关产品推荐
相关产品推荐

