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

滚动未达页面底部时加载内容,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('加载失败,请重试');
        }
    });
}

关键修改点说明

  1. 加载锁isLoading:确保同一时间只有一个AJAX请求在执行,彻底解决重复触发的问题
  2. AJAX回调解锁:不管成功还是失败,都要把isLoading设为false,防止页面陷入无法加载的状态
  3. 主动触发滚动事件:在success回调中触发$(window).trigger('scroll'),这样当新内容加载完成后,会自动检查当前滚动位置是否满足新的目标条件,如果满足就继续加载下一页

这个方案既解决了一次性加载全部内容的问题,又能保证在用户滚动过程中流畅地分批加载内容,你可以直接拿去测试~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:15:36