Smooth scroll to anchor after loading new page

53,280

As browsers automatically detect the hash and take you to that position...
It occurs to me that you could first reset the scroll position to 0 and then made the smooth scrolling.

Something like...

// to top right away
if ( window.location.hash ) scroll(0,0);
// void some browsers issue
setTimeout( function() { scroll(0,0); }, 1);

$(function() {

    // your current click function
    $('.scroll').on('click', function(e) {
        e.preventDefault();
        $('html, body').animate({
            scrollTop: $($(this).attr('href')).offset().top + 'px'
        }, 1000, 'swing');
    });

    // *only* if we have anchor on the url
    if(window.location.hash) {

        // smooth scroll to the anchor id
        $('html, body').animate({
            scrollTop: $(window.location.hash).offset().top + 'px'
        }, 1000, 'swing');
    }

});

Edit: Move the scroll(0,0)outside $(function(){...}); to prevent flickering.
Also, Snippet with working example was added.
The effect is best appreciated when viewed in full screen

        html, body {
            margin: 0;
            padding: 0;
        }
        .hidden-code {
            display: none;
            visibility: hidden;
            opacity: 0;
        }
        .header {
            background-color: #ccc;
            padding: 5px;
        }
        .header li {
            padding: 5px;
            margin: 5px;
            display: inline-block;
        }
        .articles > div {
            border: 1px solid;
            margin: 10px;
            padding: 250px 50px;
            background-color: #ccc;
        }
        div:before {
            content: attr(id);
        }
        .footer {
            text-align: center;
        }
    <div class="header">
        <ul>
            <li>page header title/navbar</li>
            <li><a class="scroll" href="#text-1">#text-1</a></li>
            <li><a class="scroll" href="#text-2">#text-2</a></li>
            <li><a class="scroll" href="#text-3">#text-3</a></li>
            <li><a class="scroll" href="#text-4">#text-4</a></li>
            <li><a class="scroll" href="#text-5">#text-5</a></li>
            <li><a class="scroll" href="#text-6">#text-6</a></li>
            <li><a class="scroll" href="#text-7">#text-7</a></li>
            <li><a class="scroll" href="#text-8">#text-8</a></li>
        </ul>
    </div>

    <div class="container">

        <div class="content">

            <div class="articles">
                <div id="text-1"></div>
                <div id="text-2"></div>
                <div id="text-3"></div>
                <div id="text-4"></div>
                <div id="text-5"></div>
                <div id="text-6"></div>
                <div id="text-7"></div>
                <div id="text-8"></div>
            </div>

        </div>

        <div class="footer">company &copy; 2015</div>

    </div>

    <div class="hidden-code">

        <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script type="text/javascript">

            // to top right away
            if ( window.location.hash ) scroll(0,0);
            // void some browsers issue
            setTimeout( function() { scroll(0,0); }, 1);

            // any position
            $(function() {
                // your current click function
                $('.scroll').on('click', function(e) {
                    e.preventDefault();
                    $('html, body').animate({
                        scrollTop: $($(this).attr('href')).offset().top + 'px'
                    }, 1000, 'swing');
                });
                // *only* if we have anchor on the url
                if(window.location.hash) {
                    // smooth scroll to the anchor id
                    $('html, body').animate({
                        scrollTop: $(window.location.hash).offset().top + 'px'
                    }, 1000, 'swing');
                }
            });
        </script>

    </div>
Share:
53,280
Mr Toad
Author by

Mr Toad

Updated on April 22, 2020

Comments

  • Mr Toad
    Mr Toad about 4 years

    I want to navigate to an anchor point on a new page, but I want the page to load at the top then immediately smooth scroll to the relevant anchor point. Can this be done?

    I am a complete newbie with Javascript.

    This is the js I currently use for smooth scrolling within the current page. I just apply a class of 'scroll' on the link.

    Thanks very much!

    <script>
    $(function(){
      $('.scroll').on('click',function(e) {
        e.preventDefault();
        $('html, body').animate({ scrollTop: $($(this).attr('href')).offset().top + 'px' }, 1000, 'swing');
      });
    });
    </script>
    
  • Mr Toad
    Mr Toad almost 9 years
    The scrolling works perfectly on the same page, but I still seem to get the initial flash on external links. It works the first couple of times, but eventually starts doing it. Strange - I must be doing something wrong!
  • gmo
    gmo almost 9 years
    Try this code locally and tell me if you find the same problems. What OS and browser you use? pastebin.com/raw.php?i=3JbPp9wn
  • Mr Toad
    Mr Toad almost 9 years
    Hey! So sorry - I have been away. This works perfectly The previous tests were done locally on OSX Yosemite testing across multiple browsers (safari, firefox, opera and Chrome). Thanks again!
  • gmo
    gmo almost 9 years
    Perfect! .. I'm glad that it has been helpful.
  • Cu7l4ss
    Cu7l4ss about 8 years
    @gmo Can you please explain why are you doing scroll(0,0) two times when an anchor is present? and why don't you take the one that is timed out into account as well when checking for the hash?
  • Luzan Baral
    Luzan Baral almost 7 years
    It is scrolling to the section, but again reverting back to top. What might be ta case?
  • gmo
    gmo almost 7 years
    @LuzanBaral Without your code, difficult to say, can you share a fiddle example?. But I presume you have another script who is scrolling to top. Try loading the page with an anchor and without this code and see if it taking you to the top.
  • Luzan Baral
    Luzan Baral almost 7 years
    @gmo it worked after I removed first 4 lines of your code. Thanks!
  • gmo
    gmo almost 7 years
    @LuzanBaral I'm glad it works for you. First four lines are useful if you load the page with an anchor, If `anchor is not used then yes, four first lines can be removed.
  • herrfischer
    herrfischer over 6 years
    Very good! When you delete first 4 lines then it is a good solution for onepagers with lots of hidden content.
  • Matt
    Matt almost 5 years
    Had to change it to $('html, body').delay(2000).animate({ scrollTop: $(window.location.hash).offset().top + 'px' },'slow'); before it worked for me.
  • Mr Toad
    Mr Toad over 4 years
    This thread hasn't been active in a while - but does anyone know how to amend the code so that the # is removed from the url when navigating from another page?
  • gmo
    gmo over 4 years
    @MrToad, It is not related to OP, who wants to scroll based on an anchor extracted from the hash in the URL. Do you maybe want to remove the hash from the url?
  • Jay Smoke
    Jay Smoke about 3 years
    @gmo lovely bro! I am about to implement this, but wanted to know is there a way to add some sort of padding to the scroll when it reaches the anchor? Currently it scrolls to the anchor and it's right at the top of the browser. Can this be done such that it scrolls to the centre of the browser and highlighted briefly?
  • gmo
    gmo about 3 years
    @JaySmoke sure, just sum any pixels you want toscrollTop function, like ie. 150 -> ...offset().top + 150 + 'px'
  • gmo
    gmo about 3 years
    @JaySmoke for highlight, you could use a callback function on complete see doc. -> api.jquery.com/animate