jQuery cross-browser "scroll to top", with animation
Asked Answered
P

8

27

Right now I'm using this:

$('#go-to-top').each(function(){
  $(this).click(function(){ 
    $('html').animate({ scrollTop: 0 }, 'slow'); return true; 
  });
});

which doesn't work in Chrome, and in Opera I get a small flicker: the browser instantly scrolls to the top, then back to the bottom and then it begins to scroll slowly back to top, like it should.

Is there a better way to do this?

Planoconcave answered 7/4, 2011 at 11:32 Comment(1)
Note that #go-to-top is an element ID, which must be unique. Calling each on something that should only contain one element may work, but is naughty. Probably you want to give your elements a class instead, and select with $('.go-to-top')Maltreat
C
93

You're returning true from the click function, so it won't prevent the default browser behaviour (i.e. navigating to thego-to-top anchor. As Mark has said, use:

$('html,body').animate({ scrollTop: 0 }, 'slow');

So your code should now look like:

$('#go-to-top').each(function(){
    $(this).click(function(){ 
        $('html,body').animate({ scrollTop: 0 }, 'slow');
        return false; 
    });
});
Coupon answered 7/4, 2011 at 11:41 Comment(4)
that was it, with return set to false it scrolls :DPlanoconcave
Still the each is absolutely unneccessary. Even if there were multiple elements with the id go-to-top, then click on its own would be more than enought!Surovy
Using html,body will cause the callback to fire twice. Just using html works for me.Quaternion
Sorry, using html,body does not cause the callback to fire twice. Indeed, it is needed for certain browsers.Coupon
Y
5

To get it to work in opera this answer proved helpful.

Putting that with your click()

$(this).click(function() {
    $(window.opera ? 'html' : 'html, body').animate({
        scrollTop: 0
    }, 'slow');
});

Code example on jsfiddle.

Side note if all you are doing with the .each() is assigning a click handler you do not need to iterate over the collection it can be simplified to this:

$('#go-to-top').click(function(){ 
    $(window.opera ? 'html' : 'html, body').animate({
        scrollTop: 0
        }, 'slow');
});

Also if there is more than one element with id #go-to-top your markup will be invalid, try switching it to a class .go-to-top

Yukoyukon answered 7/4, 2011 at 11:36 Comment(1)
Since then, Opera has switched to the WebKit engine, so I guess the special handling for it is no longer needed, and probably even harmful.Carlitacarlo
D
2

maybe something like

$('body').animate({scrollTop:0}, 'slow');

aswell as the html one.

edit >

$('#go-to-top').each(function(){
  $(this).click(function(){ 
    $('html').animate({ scrollTop: 0 }, 'slow'); return true; 
    $('body').animate({ scrollTop: 0 }, 'slow'); return true; 
    $('document').animate({ scrollTop: 0 }, 'slow'); return true; 
    $('window').animate({ scrollTop: 0 }, 'slow'); return true; 
  });
});

should cover all browsers!

Dementia answered 7/4, 2011 at 11:36 Comment(1)
Using return true on l.3 will prevent any following statement to be executedAsleep
T
1

Hm... strange, with jsFiddle I can get it to work fine in Opera (ver 11.01), but in Chrome it just jumps up to the top and doesn't animate it like you want to.

You can se the jsFiddle here if you want to: http://jsfiddle.net/H7RFU/

I hope that helps a bit, though it's not really an answer.

If what I have made isn't what your html etc looks like, please update it and add it.

Best regards,

Christian

Caveat: I haven't used the save function of jsFiddle before so I dunno for how long it it saved.

Tetracaine answered 7/4, 2011 at 11:44 Comment(0)
E
1
$(window).animate({ scrollTop: 0 }, 'slow');

It works cross-browser

Euler answered 1/3, 2013 at 8:30 Comment(0)
C
0

This will be working in all browsers. It avoids the hash tag on the url, so, the smooth scroll is done!

 $('#back-top a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {

        $('html,body').animate({

          scrollTop: target.offset().top
        }, 1000);
        return false;
      }
    }
  }); 
Classic answered 22/1, 2016 at 5:44 Comment(0)
C
0

I am using this, This is also simple

$(document).ready(function(e) {
var a = 400,
t = 1200,
l = 700,
s = e(".scrool-top");
e(window).scroll(function() {
e(this).scrollTop() > a ? s.addClass("scrool-is-visible") : s.removeClass("scrool-is-visible scrool-fade-out"), e(this).scrollTop() > t && s.addClass("scrool-fade-out")
}), s.on("click", function(a) {
a.preventDefault(), e("body,html").animate({
scrollTop: 0
}, l)
})
})
Coshow answered 7/8, 2016 at 22:34 Comment(0)
B
0

I have a smooth solution in two ways: smooth scrolling and a smooth button.

With JavaScript disabled, it´s just a link on the bottom of the page to the anchor top.
(# as href can be pretty unstable.)

With JavaScript enabled:

  1. Hide the div containing the link (to avoid flickering).
  2. Fix the position of the div at the bottom right border of the window.
  3. Remove the href attribute and add click handler for smooth scrolling. (keeps URL and browser history tidy and I need no return or preventDefault in the scrolling function)
  4. Fade div in / out depending on scroll position:
    Display link only if scroll position > window height.
  5. Update the position on resize.

HTML

<body>
    <a name="top"></a>
    ...
    <div id="scrolltotop" style="display:block;text-align:right">
        <a href="#top" title="scroll to top"><img src="scrolltotop.png" alt="scroll to top"></a>
    </div>
</body>

jQuery

function scrolltotop_display()
{
    var el=$('#scrolltotop');
    if((window.pageYOffset||document.documentElement.scrollTop)>window.innerHeight)
    { if(!el.is(':visible')) { el.stop(true, true).fadeIn(); } }
    else { if(!el.is(':animated')) { el.stop(true, true).fadeOut(); }}
}
function scrolltotop_position()
{
    var el=$('#scrolltotop');
    el.css('top', window.innerHeight-100);
    el.css('left', window.innerWidth-100);
    scrolltotop_display();
}
$(window).on('load', function(){
    $('#scrolltotop').css('display', 'none');
    $('#scrollToTop').css('position', 'fixed');
    scrolltotop_position();
    $('#scrollToTop a').removeAttr('href');
    $('#scrollToTop a').on('click', function(){$('html, body').animate({scrollTop:0}, 500);});
});
$(window).on('scroll', scrolltotop_display);
$(window).on('resize', scrolltotop_position);
Bridwell answered 18/7, 2018 at 11:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.