Search code examples
javascriptjqueryjquery-waypoints

How to trigger event when user scrolls to the top of the page using Jquery and Waypoints?


I have a relatively standard page layout.

I have multiple

<section id="unique-id">Content</section> 

which hold the content of the page. I also have shim at the top of the page due to a fixed navbar (height: 100px).

as the user scrolls to the bottom of the page, as they reach each section, I trigger a Waypoints event, with an offset: 100. This makes sure that I am not hiding content under the menu as I go.

the issue is that when the user scrolls back up, they reach the top of the page/ the first section, with the shim above it, but the waypoints event is not triggered. I have tried playing with the offset and making it say 150 but it still does not trigger at the top.

My js code:

// FOR SCROLLING
$('body section').waypoint(function() {
    var id = $(this).attr('id');
    var subTarget = $('#sub-nav li a[href=#'+id+']');
        $('.current-sub-nav').removeClass('current-sub-nav');
        subTarget.parent('li').addClass('current-sub-nav');

}, {offset: 101 });

My html is formed like:

<header></header>
<div class="shim"></div>
<section id="uniqueid">Content</section>
<Section id="uniqueid2">Content 2</section>
<Section id="uniqueid3">Content 3</section>

The trigger happens fine between 1/2 and 2/3 but not when I scroll back up.


Solution

  • You were correct in trying to update your offset, because that is the issue. Basically, the top of the first section was never coming back across the top of the viewport and so it was not firing the waypoint. If you were to set the offset to 0, you would have had the same problem, except the waypoint would not trigger for the third section.

    Here are two solutions; I came up with some artificial markup to work against. They may need to be modified slightly to match your specific markup; given the lack of detail in the question itself.

    First Solution Fiddle - This option maintains your markup pretty much the way described. I switched the offset to 1%, and that seemed to have done the trick.

    HTML

    <header></header>
    <nav class="navbar navbar-inverse navbar-default navbar-fixed-top" role="navigation">
        <div class="container">
            <ul id="sub-nav" class="nav navbar-nav">
                <li class="active"><a href="#uniqueid">Content</a></li>
                <li><a href="#uniqueid2">Content2</a></li>
                <li><a href="#uniqueid3">Content3</a></li>
            </ul>
        </div>
    </nav>
    <div class="shim" style="margin-top: 50px;"></div>
    <section id="uniqueid" style="height: 600px; background-color: red;">Content</section>
    <section id="uniqueid2" style="height: 600px; background-color: white;">Content 2</section>
    <section id="uniqueid3" style="height: 600px; background-color: blue;">Content 3</section>
    

    Javascript

    // FOR SCROLLING
    $('body section').waypoint(function () {
        var id = $(this).attr('id');
        var subTarget = $('#sub-nav li a[href=#' + id + ']');
        $('.active').removeClass('active');
        subTarget.parent('li').addClass('active');    
    }, { offset: '1%' });
    





    Second Solution Fiddle - This solution modifies your markup slightly by removing the shim and adding a margin to the top of the first container.

    HTML

    <header></header>
    <nav class="navbar navbar-inverse navbar-default navbar-fixed-top" role="navigation">
        <div class="container">
            <ul id="sub-nav" class="nav navbar-nav">
                <li class="active"><a href="#uniqueid">Content</a></li>
                <li><a href="#uniqueid2">Content2</a></li>
                <li><a href="#uniqueid3">Content3</a></li>
            </ul>
        </div>
    </nav>
    <section id="uniqueid" style="height: 1100px; background-color: red; margin-top: 51px;">Content</section>
    <section id="uniqueid2" style="height: 1100px; background-color: white;">Content 2</section>
    <section id="uniqueid3" style="height: 1100px; background-color: blue;">Content 3</section>
    

    Javascript

    // FOR SCROLLING
    $('body section').waypoint(function () {
        var id = $(this).attr('id');
        var subTarget = $('#sub-nav li a[href=#' + id + ']');
        $('.active').removeClass('active');
        subTarget.parent('li').addClass('active');
    
    }, { offset: 50 });