简体   繁体   English

jQuery滚动事件触发两次

[英]jQuery scroll event fires twice

I'm working on making an infinite scroll function for a page and am running into an issue where it appears that the $( window ).scroll() function is firing twice. 我正在为页面制作无限滚动功能,并且遇到了一个问题,其中似乎$( window ).scroll()函数触发了两次。 I've seen similar questions on stackoverflow, but they seem to be related to fast scrolls and not having something in place to check weather the request has already been sent. 我已经在stackoverflow上看到了类似的问题,但是它们似乎与快速滚动有关,并且没有适当的位置检查天气是否已经发送了请求。 Here's the code that I'm working with right now, I imagine that its something easy that I'm missing here. 这是我现在正在使用的代码,我想这很容易在这里丢失。

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 );
        });
    }
});

The face that when I log out the scrollcount variable and the return from scrollTop() I get the same number twice seems to tell me that the event is actually firing twice at the same time for some reason. 当我注销scrollcount变量并从scrollTop()返回时,遇到两次相同的数字的事实似乎告诉我,由于某种原因,该事件实际上实际上同时触发了两次。 It seems that if it were firing twice, one after the other, the loading variable would be set to false and not fire that second time. 看来,如果它触发两次,一次又一次,则加载变量将设置为false,而第二次不会触发。 Like I said, I imagine that it's something super simple that I'm missing. 就像我说的,我想这是我所缺少的超级简单的东西。 Thanks for your help! 谢谢你的帮助!

My first guess is you have the event listener applied twice, wherever this code is. 我的第一个猜测是,无论代码位于何处,您都两次应用了事件侦听器。

Try adding $(window).unbind('scroll'); 尝试添加$(window).unbind('scroll'); before $(window).scroll 在$(window).scroll之前

The loading variable would be false for when it fires twice because false is set on a timeout, after an async call 加载变量两次触发时将为false,因为在异步调用后,超时设置为false

var timeout;

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

Use this code. 使用此代码。

I tinkered with this and tried some of the above solutions. 我对此进行了修改,并尝试了上述一些解决方案。 None work 100% with major browsers for my use case (which was a simple scroll loader). 在我的用例(这是一个简单的滚动加载器)中,没有一种可以与主要浏览器100%兼容。 To avoid using setTimeout and ONLY execute a specific function within a set duration, create this function object literal: 为了避免使用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;
        }
};

And then add this to the function you have bound to your scroll event: 然后将其添加到绑定到滚动事件的函数中:

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

This way, the scrollbar event can fire off as weirdly as it wants but your attached function will never execute twice within a certain interval. 这样,scrollbar事件可以根据需要怪异地触发,但是您附加的函数在一定间隔内将永远不会执行两次。 The double-firing of the scroll event happens much faster than 500ms but since my usage was for a scroll loader, all I needed to ensure was that the function fired once within a 500ms window. 滚动事件的两次触发发生的时间比500ms快得多,但是由于我使用的是滚动加载器,因此我需要确保的功能是在500ms窗口内触发一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM