Question

I'm using the jQuery Waypoints plugin to dynamically load the next article in a series when the reader gets near the end of the current article. So one waypoint triggers that ajax request.

I also have a waypoint attached to each article's wrapper element that triggers both when the article nears the top of the screen (when scrolling down) and when it comes about half-way onto the screen (when scrolling up) - these functions update the title and URL of the page in the address bar.

This is all working, but I'm finding that once I get several articles down, when waypoints refreshes (as happens when you add a new waypoint), all of the previous articles' waypoints are triggered, so I can see the title bar quickly racing through all of the previous titles/URLs.

I thought adding continuous: false to the .entry-wrapper waypoints would fix it (from the docs;: "if false, it will only trigger if it is the last waypoint."), but alas, it does not.

Any ideas? Code follows:

/*
    Load the next entry via AJAX when we near the end of each entry 
*/
$('.load-trigger').waypoint(
    function()
    {
        url = $('.load-next:last').data('url');
        if(url)
        {
            $.get(url, function(data)
            {
                /*
                    We only want the content    
                */
                entry = $(data).find('.entry-wrapper').hide();
                /*
                    Add it to the DOM   
                */
                $('.content').append(entry);
                /*
                    Fade-in 
                */
                $(entry).fadeIn(500, function()
                {
                    /*
                        When scrolling down, push a new history state when the new entry reaches the top of the window  
                    */
                    $('.entry-wrapper').waypoint(function(direction)
                    {
                        if(direction === 'down')
                        {
                            history.pushState('', $(this).data('title'), $(this).data('url'));
                            document.title = $(this).data('title');
                        }
                    },
                    {
                        continuous: false,
                        offset: '100px'
                    });
                    /*
                        When scrolling back up, push a new history state when the previous entry is filling roughly half of the window
                        (see offset)
                    */
                    $('.entry-wrapper').waypoint(function(direction)
                    {
                        if(direction === 'up')
                        {
                            history.pushState('', $(this).data('title'), $(this).data('url'));
                            document.title = $(this).data('title');
                        }
                    },
                    {
                        continuous: false,
                        offset: function(){ return ($(this).height() * -1) + ($.waypoints('viewportHeight') / 2) }
                    });
                });
            });
        }
    },
    {
        offset: '120%'
    }
);

Simplified markup:

<div class="content">
    <div class="entry-wrapper" data-title="Foo baz bar" data-url="http://foo.bar/bing>
        ...
        <div class="load-next" data-url="http://foo.bar/baz"></div>
    </div>
</div>
<div class="load-trigger"></div>
Was it helpful?

Solution

Found my error: I was adding the history-related waypoints to every previous entry each time a new entry was loaded ($('.entry-wrapper').waypoint(function(direction)...). Instead I needed to be specific:

/*
    When scrolling down, push a new history state when the new entry reaches the top of the window  
*/
$(entry).waypoint(function(direction)
{
    if(direction === 'down')
    {
        history.pushState('', $(this).data('title'), $(this).data('url'));
        document.title = $(this).data('title');
    }
},
{
    continuous: false,
    offset: '100px'
});
/*
    When scrolling back up, push a new history state when the previous entry is filling roughly half of the window
    (see offset)
*/
$(entry).waypoint(function(direction)
{
    if(direction === 'up')
    {
        history.pushState('', $(this).data('title'), $(this).data('url'));
        document.title = $(this).data('title');
    }
},
{
    continuous: false,
    offset: function(){ return ($(this).height() * -1) + ($.waypoints('viewportHeight') / 2) }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top