jQuery滚动事件触发两次

时间:2014-04-29 18:51:29

标签: javascript jquery infinite-scroll

我正在为页面制作无限滚动功能,并且遇到$( window ).scroll()函数出现两次触发的问题。我在stackoverflow上看到了类似的问题,但它们似乎与快速滚动相关,并且没有适当的位置来检查请求已经发送的天气。这是我现在正在使用的代码,我想这里我很容易找到它。

var loading = false;
var scrollcount = 0;

$( window ).scroll( function(){
    scrollcount++;
    var scrolling = $( document ).scrollTop();
    var position = $( "#ajax-load" ).offset();
    if( scrolling + $( window ).height() > position.top - 200 && loading == false ){
        console.log( loading ); //returns 2 falses
        console.log( scrollcount ); //returns 2 of the same number
        console.log( $( document ).scrollTop() ); //returns same number
        loading = true;
        $( "#ajax-load" ).css( "display", "block" );
        $.get( "url/to/my/script", info )
        .done( function( data ){
            //here's where the items are appended to the document
            setTimeout( function(){
                loading = false;
            }, 5000 );
        });
    }
});

当我注销scrollcount变量并从scrollTop()返回时,我得到两次相同的数字似乎告诉我事件实际上是由于某种原因同时触发了两次。似乎如果它一次又一次地发射两次,那么加载变量将被设置为假而第二次不会发射。就像我说的那样,我想这是一件非常简单的东西,我很想念。谢谢你的帮助!

3 个答案:

答案 0 :(得分:5)

我的第一个猜测是,无论此代码在哪里,都会将事件监听器应用两次。

尝试添加$(窗口).unbind(' scroll');在$(窗口)之前.scroll

加载变量在两次触发时为false,因为在异步调用后超时时设置为false

答案 1 :(得分:2)

var timeout;

$(window).scroll(function() {
    clearTimeout(timeout);  
    timeout = setTimeout(function() {
        // do your stuff
    }, 50);
});

使用此代码。

答案 2 :(得分:0)

我对此进行了修改,并尝试了上述一些解决方案。在我的用例(这是一个简单的滚动加载器)中,没有一种可以与主要浏览器100%兼容。为了避免使用setTimeout并仅在设定的持续时间内执行特定功能,请创建以下功能对象文字:

var hlpr = {
        lastExec: new Date().getTime(),
        isThrottled: function (timeout) {
            if ((new Date().getTime() - this.lastExec) < timeout) {
                console.log('returned');
                return false;
            }
            this.lastExec = new Date().getTime();
            return true;
        }
};

然后将其添加到绑定到滚动事件的函数中:

if (!hlpr.isThrottled(500))
     return;

这样,scrollbar事件可以根据需要异常触发,但是您附加的函数在特定间隔内将永远不会执行两次。滚动事件的两次触发发生的时间比500ms快得多,但是由于我使用的是滚动加载器,因此我需要确保的功能是在500ms窗口内触发一次。