admin管理员组

文章数量:1289735

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. 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. 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. 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. Like I said, I imagine that it's something super simple that I'm missing. Thanks for your help!

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. 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. 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. 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. Like I said, I imagine that it's something super simple that I'm missing. Thanks for your help!

Share Improve this question asked Apr 29, 2014 at 18:51 Eric StromEric Strom 7259 silver badges21 bronze badges 2
  • Can you make a jsfiddle? – Lloyd Banks Commented Apr 29, 2014 at 18:53
  • I just made a fiddle and unfortunately am not getting the same results as I am from the site. I'll keep trying to see if I can reproduce the issue elsewhere. – Eric Strom Commented Apr 29, 2014 at 19:04
Add a ment  | 

3 Answers 3

Reset to default 6

My first guess is you have the event listener applied twice, wherever this code is.

Try adding $(window).unbind('scroll'); before $(window).scroll

The loading variable would be false for when it fires twice because false is set on a timeout, after an async call

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). To avoid using setTimeout and ONLY execute a specific function within a set duration, create this function object literal:

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. 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.

本文标签: javascriptjQuery scroll event fires twiceStack Overflow