jquery无限滚动 - 阻止多次调用

时间:2015-11-19 08:35:48

标签: javascript jquery ajax events infinite-scroll

我有一个分页网站,一旦用户滚动到页面底部,我就会加载下一页。我正在使用jquery的.on('scroll', this.detectScroll())绑定滚动到一个函数,该函数检查用户当前在页面中的位置,如果它们到达底部则加载下一页。

detectScroll: function() {
    var controller = this;

    $(window).on("scroll", function() {
        var scrolled = $(window).scrollTop()+$(window).height();
        var scrollEnd = $(document).height();

        var distance = scrollEnd - scrolled; // distance from page edge

        if (distance === 0) { 
            controller.loadPage();
        }
    });

}

问题是,由于滚动事件经常发生,因此在加载下一页之前会多次调用该函数,结果是加载了许多页并同时附加到视图中。

我尝试在loadPage()函数中取消绑定事件,但我认为滚动事件侦听器的调用速度比函数启动的速度快,所以它不起作用。这是负责加载下一页的功能:

loadPage: function () {
    this.currentPage++;
    $(window).off("scroll");

    $.ajax({
        url: this.settings.pageUrl,
        type: 'GET',
        dataType: 'html',
        data: {
            page: this.currentPage
        },
        success: $.proxy(function(result) {
            // once new page inserted, start listening again
            if(result != "") {
                this.$view.append(result); // insert new page into view
                this.detectScroll();
            } 


        }, this),
        error: $.proxy(function(result) {
            // error
            this.$userContainer.html('<h3 class="text-center">Error loading content...</h3>');
        }, this)
    });
},

我尝试在loadPage()加载后立即取消绑定侦听器,并在回调中再次绑定它,但它也不起作用。我认为最好的解决方案是只在一定的时间间隔内收听滚动事件 - 比如说,每200ms只听一次。这样可以防止多次触发相同的功能。但我在网上找不到任何东西,所以请给我一些提示。

1 个答案:

答案 0 :(得分:0)

var _xhr = []; // global

loadPage: function () {
    this.currentPage++;
    $(window).off("scroll");

    [].forEach.call(_xhr, function(i, j){
       i.abort();
       _xhr.splice(j, 1);
    });

    var x = $.ajax({
        url: this.settings.pageUrl,
        type: 'GET',
        dataType: 'html',
        data: {
            page: this.currentPage
        },
        success: $.proxy(function(result) {
            // once new page inserted, start listening again
            if(result != "") {
                this.$view.append(result); // insert new page into view
                this.detectScroll();
            } 


        }, this),
        error: $.proxy(function(result) {
            // error
            this.$userContainer.html('<h3 class="text-center">Error loading content...</h3>');
        }, this)
    });
    _xhr.push(x);
},

将所有请求保留在数组中,然后在发出任何新请求之前,只需.abort所有先前的请求,然后从数组中弹出它们。