51

I was trying to use jQuery's page scroll inside some pages and could successfully make a smooth page scroll. The only problem I have now is when attempting to do that from different page. What I mean by that is if I click on a link in a page, it should load the new page and then scroll to the specific div element.

Here is the code I used to scrolling inside the page:

var jump=function(e)
{
       //prevent the "normal" behaviour which would be a "hard" jump
       e.preventDefault();
   //Get the target
   var target = $(this).attr("href");
   //perform animated scrolling
   $('html,body').animate(
   {
           //get top-position of target-element and set it as scroll target
           scrollTop: $(target).offset().top
   //scrolldelay: 2 seconds
   },2000,function()
   {
           //attach the hash (#jumptarget) to the pageurl
           location.hash = target;
   });

}

$(document).ready(function()
{
       $('a[href*=#]').bind("click", jump);
       return false;
});

I hope the idea is clear.

Thanks

Very important Note: This code I posted above works great inside the same page, but what I'm after is to click a link from one page and go to another one and then scroll to the target. I hope it is clear now. Thanks

Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
Digital site
  • 4,431
  • 12
  • 48
  • 72
  • So basically the idea is to load the page, with ajax I presume, and then make a smooth scroll over to the target? so something like how you can navigate through pages on [acko.net](http://acko.net/)? – sg3s Mar 25 '12 at 20:10
  • yes, something like this, but not to load the page before clicking the button. meaning click url first to move to another page then after the page load, it scrolls down to the div element. look like someone answered already. – Digital site Mar 26 '12 at 13:19

7 Answers7

66

You basically need to do this:

  • include the target hash into the link pointing to the other page (href="other_page.html#section")
  • in your ready handler clear the hard jump scroll normally dictated by the hash and as soon as possible scroll the page back to the top and call jump() - you'll need to do this asynchronously
  • in jump() if no event is given, make location.hash the target
  • also this technique might not catch the jump in time, so you'll better hide the html,body right away and show it back once you scrolled it back to zero

This is your code with the above added:

var jump=function(e)
{
   if (e){
       e.preventDefault();
       var target = $(this).attr("href");
   }else{
       var target = location.hash;
   }

   $('html,body').animate(
   {
       scrollTop: $(target).offset().top
   },2000,function()
   {
       location.hash = target;
   });

}

$('html, body').hide();

$(document).ready(function()
{
    $('a[href^=#]').bind("click", jump);

    if (location.hash){
        setTimeout(function(){
            $('html, body').scrollTop(0).show();
            jump();
        }, 0);
    }else{
        $('html, body').show();
    }
});

Verified working in Chrome/Safari, Firefox and Opera. I don't know about IE though.

peterh
  • 11,875
  • 18
  • 85
  • 108
Petr Vostrel
  • 2,324
  • 16
  • 23
  • thanks for the effort. I believe there is something wrong with the code "long one" because it didn't work for me and I don't why...!! I think there is a use of **window.** to make it work the way I'm looking after. – Digital site Mar 25 '12 at 19:57
  • 3
    I've put the working example on-line: http://vostrel.cz/so/9652944/page.html Also I've noticed, that the script above didn't show the hidden body with no hash. Fixed it above by adding a `else` clause to the condition in `.ready()` – Petr Vostrel Mar 26 '12 at 10:34
  • 2
    Thanks mate. That was a brilliant solution. That's exactly what I want. now I can add any effect on my own. you got the bounty points first, and you deserved it. – Digital site Mar 26 '12 at 13:25
  • 2
    It's weird, when I try to use this code, my whole page disapear? – Dikeneko Aug 12 '16 at 11:25
  • 1
    @PetrVostrel for me your link doesnt animate scroll when jumping to second page. It jumps immediately to the ID ... It actually works for you? – trainoasis Jan 25 '18 at 13:34
  • @trainoasis it indeed does. In all listed browsers. – Petr Vostrel Jan 27 '18 at 02:24
  • 1
    Yeah, doesn't work for me either - makes the page flicker if there's lots of content but then just arrives at the target... – Julix Feb 14 '18 at 23:43
  • This did not work for me. When coming from a different page after clicking an anchor with a hash tag, I had to set a timeout function to allow time to calculate the scroll. Because browsers store your page location, scrolling to a specific location can be troublesome on page load. This is what worked for me: `if (window.location.hash.length > 0) { setTimeout(function() { window.scrollTo(0, $(window.location.hash).offset().top); }, 450); }` – jottin Jul 13 '22 at 14:53
26

On the link put a hash:

<a href="otherpage.html#elementID">Jump</a>

And on other page, you can do:

$('html,body').animate({
  scrollTop: $(window.location.hash).offset().top
});

On other page, you should have element with id set to elementID to scroll to. Of course you can change the name of it.

Sarfraz
  • 377,238
  • 77
  • 533
  • 578
  • thanks for the answer. I will try it out and provide some feedback whenever it is done. Thanks again – Digital site Mar 11 '12 at 07:43
  • I tried it, but didn't work. I guess either I'm missing something or there is something not correct. I made a hash on **a href link** and still not sure where to place the other code. And the result is that when I click on the link, it goes directly to the page at the div without scrolling to it, which is strange. I believe the code has something to do with this so the smooth scroll works... any idea how to get around with this? – Digital site Mar 11 '12 at 08:11
  • Thanks all for the replies. I will check all your answers whenever I finish what I have in my hands now. – Digital site Mar 24 '12 at 12:44
  • This works for me. I comment it for somebody who need it – Alberto Rubio May 18 '16 at 05:01
  • @Sarfraz if possible then can you check this https://stackoverflow.com/questions/56430914/the-section-heading-is-hiding-while-using-smooth-scroll-from-one-page-to-another – questionbank Jul 03 '19 at 09:14
  • This is the short & sweet solution. And to make the scroll appear smooth, you simply add the milliseconds to the animate() method. – Ron16 Oct 24 '19 at 13:42
11

Combining answers by Petr and Sarfraz, I arrive at the following.

On page1.html:

<a href="page2.html#elementID">Jump</a>

On page2.html:

<script type="text/javascript">
    $(document).ready(function() {
        $('html, body').hide();

        if (window.location.hash) {
            setTimeout(function() {
                $('html, body').scrollTop(0).show();
                $('html, body').animate({
                    scrollTop: $(window.location.hash).offset().top
                    }, 1000)
            }, 0);
        }
        else {
            $('html, body').show();
        }
    });
</script>
zanetu
  • 3,740
  • 1
  • 21
  • 17
6

I would like to recommend using the scrollTo plugin

http://demos.flesler.com/jquery/scrollTo/

You can the set scrollto by jquery css selector.

$('html,body').scrollTo( $(target), 800 );

I have had great luck with the accuracy of this plugin and its methods, where other methods of achieving the same effect like using .offset() or .position() have failed to be cross browser for me in the past. Not saying you can't use such methods, I'm sure there is a way to do it cross browser, I've just found scrollTo to be more reliable.

Fresheyeball
  • 29,567
  • 20
  • 102
  • 164
  • Thanks for the answer. This solution I know and as I recall, it is used for the scroll within a page, not from a page to another page and then scroll to the target. sorry, but thanks anyways for trying. – Digital site Mar 25 '12 at 19:45
  • It is only possible to scroll within a document, or document elements. I am not understanding what you mean by 'page' anymore. You cannot scroll to another document. – Fresheyeball Mar 26 '12 at 16:37
  • maybe it is a little confusing. when you click on a link on page A to go page B then scroll down to the div element. This is what I want to achieve, but it is o.k, the solution is up there. thanks for trying though – Digital site Mar 26 '12 at 19:45
  • 2
    yup my solution does that. No worries though, pick the answer that works for you. – Fresheyeball Mar 27 '12 at 00:55
  • I know that this is old but it's not scrollto more of the use of plugin to scroll.local – Akyl Sep 07 '12 at 14:25
  • I am not familiar with scroll.local – Fresheyeball Sep 07 '12 at 14:44
2

I made a reusable plugin that can do this... I left the binding to events outside the plugin itself because I feel it is too intrusive for such a little helper....

jQuery(function ($) {

    /**
     * This small plugin will scrollTo a target, smoothly
     *
     * First argument = time to scroll to the target
     * Second argument = set the hash in the current url yes or no
     */
    $.fn.smoothScroll = function(t, setHash) {
        // Set time to t variable to if undefined 500 for 500ms transition
        t = t || 500;
        setHash = (typeof setHash == 'undefined') ? true : setHash;

        // Return this as a proper jQuery plugin should
        return this.each(function() {
            $('html, body').animate({
                scrollTop: $(this).offset().top
            }, t);

            // Lets set the hash to the current ID since if an event was prevented this doesn't get done
            if (this.id && setHash) {
                window.location.hash = this.id;
            }
        });
    };

});

Now next, we can onload just do this, check for a hash and if its there try to use it directly as a selector for jQuery. Now I couldn't easily test this at the time but I made similar stuff for production sites not long ago, if this doesn't immediatly work let me know and I'll look into the solution I got there.

(script should be within an onload section)

if (window.location.hash) {
    window.scrollTo(0,0);
    $(window.location.hash).smoothScroll();
}

Next we bind the plugin to onclick of anchors which only contain a hash in their href attribute.

(script should be within an onload section)

$('a[href^="#"]').click(function(e) {
    e.preventDefault();

    $($(this).attr('href')).smoothScroll();
});

Since jQuery doesn't do anything if the match itself fails we have a nice fallback for when a target on a page can't be found yay \o/

Update

Alternative onclick handler to scroll to the top when theres only a hash:

$('a[href^="#"]').click(function(e) {
    e.preventDefault();
    var href = $(this).attr('href');

    // In this case we have only a hash, so maybe we want to scroll to the top of the page?
    if(href.length === 1) { href = 'body' }

    $(href).smoothScroll();
});

Here is also a simple jsfiddle that demonstrates the scrolling within page, onload is a little hard to set up...

http://jsfiddle.net/sg3s/bZnWN/

Update 2

So you might get in trouble with the window already scrolling to the element onload. This fixes that: window.scrollTo(0,0); it just scrolls the page to the left top. Added it to the code snippet above.

sg3s
  • 9,411
  • 3
  • 36
  • 52
  • Thanks for the answer. The code is good, but can't be used from different page to the other page and then scroll down to the target. Thanks again for the effort. – Digital site Mar 25 '12 at 19:49
  • If thats the case your idea wasn't clear to any of us... If you refine the question I am willing to give it another try :| – sg3s Mar 25 '12 at 19:53
  • Thanks, but I have no problem at all hearing out any answer. if the bounty point expired, I will re-set new one since this question is important for me. Thanks again – Digital site Mar 25 '12 at 19:59
2
function scroll_down(){
    $.noConflict();
    jQuery(document).ready(function($) {
        $('html, body').animate({
            scrollTop : $("#bottom").offset().top
        }, 1);
    });
    return false;
}

here "bottom" is the div tag id where you want to scroll to. For changing the animation effects, you can change the time from '1' to a different value

  • Thanks @vijayrk for the answer. This code is also for the scroll within the page, not from one page to another to scroll the target. – Digital site Mar 25 '12 at 19:47
  • So does it mean that you want to write the jquery in the parent page for the effect to happen on a child page? i.e you have pageA where you have link to pageB. PageB has a div called - "abc". So does it mean that you want to write the jquery in PageA so that when you click on PageB, it takes to divid- abc in pageB? –  Mar 25 '12 at 23:36
  • not really, mate. I have a link for page B in page A. when I click that link, I go to page B and the scroll down to the div element C... – Digital site Mar 26 '12 at 13:22
0

I've written something that detects if the page contains the anchor that was clicked on, and if not, goes to the normal page, otherwise it scrolls to the specific section:

$('a[href*=\\#]').on('click',function(e) {

    var target = this.hash;
    var $target = $(target);
    console.log(targetname);
    var targetname = target.slice(1, target.length);

    if(document.getElementById(targetname) != null) {
         e.preventDefault();
    }
    $('html, body').stop().animate({
        'scrollTop': $target.offset().top-120 //or the height of your fixed navigation 

    }, 900, 'swing', function () {
        window.location.hash = target;
  });
});