如何在ajax请求完成之前停止监听事件

时间:2013-01-04 17:42:15

标签: javascript jquery

我正在创建一个“滚动到底部”的新闻Feed,当用户滚动到页面底部时,该新闻源会填充新闻。

我有以下代码(通过Check if a user has scrolled to the bottom):

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
       //Ajax Request
   }
});

如何确保用户不会向上滚动,然后在完成ajax请求之前再次向下滚动以填充新闻。换句话说,什么是一个干净的方式来暂停它直到ajax请求完成并填写其结果

5 个答案:

答案 0 :(得分:3)

这样的事情:

var request_pending = false;

function at_bottom_of_page() {
    return $(window).scrollTop() + $(window).height() > $(document).height() - 100;
}

$(window).scroll(function() {
    if (request_pending) {
        return;
    }               
    if (at_bottom_of_page()) {
        request_pending = true;
        doAjax(function (moar_news) {
            render_news(moar_news);
            request_pending = false;
        });
    }
});

答案 1 :(得分:1)

只需使用变量来标记是否存在未完成的ajax请求。如果是这样,不要再提出要求。否则获取数据。 我的想法是让用户滚动,为什么要阻止UI。在这种情况下,它就像进行同步通话一样。

var isLoading = false;
//event handler
$(window).scroll(function () {
   // check height..
   // make an ajax request if isLoading is false
   if (!isLoading) {
       $.ajax(/* .. */, success: function () {
           isLoading = false;
       }, 
       error: function () {
           isLoading = false;
       });
       isLoading = true;
   }
}

如果您仍想在ajax响应之前停止侦听事件,只需删除绑定并在ajax响应处理程序中重新附加它。

var isLoading = false;
addScrollEvent();

function scrollHandler(e) {
   // check height..
   // make an ajax request if isLoading is false
   if (!isLoading) {
       $.ajax(/* .. */, success: function () {
           isLoading = false;
           addScrollEvent();
       }, 
       error: function () {
           isLoading = false;
           addScrollEvent();
       });
       $(window).off('scroll', scrollHandler);
   }
}

function addScrollEvent() {
    $(window).on('scroll', scrollHandler);
}

答案 2 :(得分:0)

在发出AJAX请求之前,取消绑定scroll处理程序。处理完AJAX响应后,重新绑定scroll处理程序。您需要为scroll处理程序指定一个名称以启用解除绑定和重新绑定:

$(window).scroll(function scrollHandler() {
    if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
        $(window).off("scroll", scrollHandler);
        $.ajax({
            ...
            complete: function() {
                $(window).scroll(scrollHandler);
            }
        });
    }
});

答案 3 :(得分:0)

不是这样的答案,而是一条不适合评论的说明。

对于IE6 / IE7 / IE8,.scroll表现不佳,并且会在每个滚动中调用几十次(如果不是数百次)回调。在我们的项目中,我们使用名为.detachedScroll的包装函数来防止这种行为:

/**
* Detached scroll prevents freezing in IE<=8
*/
if($.browser.msie && parseInt($.browser.version, 10) <= 8) {
    $.fn.scrollDetached = function(callback) {
        return $(this).each(function() {
            var oThis = this;
            clearInterval(this.detachedScrollInterval);
            this.detachedScrollInterval = setInterval(function() {
                if (oThis.hasScrolled) {
                    oThis.hasScrolled = false;
                    // Calling detached scrolling callback
                    callback();
                }
            }, 500);
            $(this).scroll(function() {
                // There was a scrolling event
                oThis.hasScrolled = true;
            });
        });
    };
} else {
    $.fn.scrollDetached = $.fn.scroll;
}

答案 4 :(得分:0)

您可以使用.off()删除事件处理程序。

var attachEvent = function(){

    $(window).scroll(function() {

        $(window).off("scroll");
        $.ajax("example.php").done(function() { 

            //If you want to reattach event
            attachEvent(); 
        });            
    });
};

attachEvent();