Search code examples
javascripthtmlbookmarks

Smooth scrolling to HTML bookmark


I have the following markup

<!DOCTYPE html>
<html>
    <head>
        <title>Blah</title>
    </head>
    <body>
        <header id='navigation'>
            <nav>
                <a rel='bookmark' href='#introduction'>Home</a>
            </nav>
        </header>
        <section id='content'>
            <section id='introduction'>
                <header>
                    <h1>Welcome</h1>
                    <a href='#navigation'>Back to top></a>
                </header>
            </section>
        </section>
    </body>
</html>

So you can click on Home and get to the introduction section with a bookmark. You can then get back to the navigation by clicking Back to top.

This will work in all browsers.

What I want to do is add a javascript listener somehow so that if Javascript is enabled on the browser it listens for bookmarks and smooth scrolls to the bookmark.

Thinking out loud, I could add an onchange listener to the location bar, parse the location and check for anything after a #. I could get the element id of the text after this character and implement a smooth scrolling algorithm? I don't think this would negate the UA scrolling however.

I could also parse the DOM for links that contain # links and add javascript onclick smoothScoll(bookmark_name) events and remove the bookmark so the link will just be '#' then in the smoothScroll do the scrolling and add it to the location bar after the #.

I would like to learn to do this with javascript and not jQuery.

Anyone got any ideas for doing this. I want to leave the HTML as is and add javascript events in my initPage() which means that I know javascript is enabled.

Thanks

Matt


Solution

  • You can add a click listener on your a#href elements, and ensure that the click returns false, this way you will negate the UA scroll. After that, you'll have to manually scroll or animate the scrolling property to match the link's offsetTop.

    Here's a js fiddle using jQuery to get you going: http://jsfiddle.net/ZtbVQ/1/. You only have to translate the jQuery calls to pure js calls.