Customizing scroll speed

Great! Our navbar items are now automatically updated based on the user's scroll position. Easy, huh? But we're not quite done yet. The transition between sections actually feels quite rough. The page literally jumps from one section to another. Such a jerky movement is not very pleasing. Instead, we should improve the user experience of our website by making this transition between sections smoother. We can quite easily accomplish this by customizing the scroll speed of our page by using jQuery. The first step in this task involves automating the scroll, that is, forcing a scroll event to a target on the page using jQuery, without the user needing to actually perform a scroll operation. The second step involves defining the speed of such a scroll operation.

As it turns out, the developers behind jQuery already thought about both of these steps by providing us with the animate   method. As its name implies, this method allows us to apply an animation to a given set of HTML elements. Furthermore, we can specify the duration of this animation (or use jQuery's default value). If you take a look at the jQuery documentation for animate (http://api.jquery.com/animate/), you will see that one of the possible parameters is scrollTop . Therefore, by writing {scrollTop: target} we can automatically scroll to target ( target being the target location of the scroll).

Now, before we can apply our animation, we must ask ourselves on which element the animation should take effect. Well, the nesting of our HTML document takes the form of the following elements:

body

  #welcome

  #services

  #gallery

  #about

  #contact

Furthermore, the scroll serves to navigate between elements. Therefore, it makes sense to apply the animation to the parent element of our HTML document:

    $('body').animate({
        scrollTop: target
    });

Great! So, we have told our browser to apply a scroll animation to the given target. But what exactly is the target? How do we define it? Well, our navbar items are anchor tags, and the anchor's href denotes the section to which an internal scroll should apply. Therefore, we would need to access the individual navbar's href target and then use this as the target for our scroll animation. Luckily, this too is easy to do using jQuery. We first need to add an event listener to each navbar item. Then, for each clicked anchor, we extract the element to which its href attribute refers. We then determine this element's offset and pass this offset to our scroll animation.

To add an event listener to an element, we use jQuery's on method and pass click as a parameter to denote that we want to capture an on-click event:

    $("nav div ul li a").on('click', function(evt) {
    });

Note how our selector only identifies anchor tags that are located within an unordered list inside a div . This ensures that only navigation menu items are being matched, as our markup should not contain any other anchor tags that are located inside list items belonging to a navigation element.

From within our event listener, we can access the object on which the click was performed using the this keyword. Thus, our clicked object will always be an anchor instance, and we can access the contents of its href. Specifically, we can access the string that follows the hash symbol within the href . To do this, all we have to write is $(this).prop (hash) or (better and more concise) this.hash

Remember that the string following the hash within a href identifies an internal element within the HTML document. We can therefore use the extracted string as a jQuery selector to get jQuery to retrieve the desired instance of the HTML element. All that we need to do then is use jQuery's offset() method to calculate our element's coordinates for us:

    $("nav ul li a").on('click', function(evt) {
      var offset = $(this.hash).offset();
    });

Voila! We are almost done! Let's piece it all together, wrap the code into a script tag, and place it into the head of our HTML document:

    <script type="text/javascript"> 
        $(document).ready(function() {
            $("nav div ul li a").on('click', function(evt) {
                var offset = $(this.hash).offset();
                $('body').animate({
                    scrollTop: offset.top
                });
            });
        });
    </script>

Save the document and try it out in your browser. Our code executes correctly. But something still isn't quite right. Did you notice the odd flicker as you clicked on the navbar items? This is because the anchor tag on which we are clicking still tells the browser to jump to the specified internal element. At the same time, we also instruct our browser to animate a scroll to the element. To resolve this duplication, we have to prevent the on-click event from trickling down to the anchor tag once it reaches our event listener. To do this, we call preventDefault on the event:

    $("nav div ul li a").on('click', function(evt) {
        evt.preventDefault();
       //...  
    });

Apply the changes, save, refresh, and try again. Great! Our custom scroll works! But there is one last annoyance. Clicking on the drop-down menu that launches our Profile and Settings modal dialogs. Did you notice how their anchor tags link to a plain hash symbol? Let's deal with this corner case by checking whether jQuery's offset() method can successfully execute an offset. To do this, we must wrap our call to animate within an if statement, so that our final block of code is as follows:

    <script type="text/javascript"> 
        $(document).ready(function() {
            $("nav div ul li a").on('click', function(evt) {
                evt.preventDefault();
                var offset = $(this.hash).offset();
                if (offset) {
                    $('body').animate({
                        scrollTop: offset.top
                    })
                }
            });
        });
    </script>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset