jQuery scrollTop not working in Chrome but working in Firefox
Asked Answered
F

16

80

I have used a scrollTop function in jQuery for navigating to top, but strangely 'the smooth animated scroll' stopped working in Safari and Chrome (scrolling without smooth animation) after I made some changes.

But it is still working smoothly in Firefox. What could be wrong?

Here is the jQuery function I used,

jQuery:

$('a#gotop').click(function() {
    $("html").animate({ scrollTop: 0 }, "slow");
    //alert('Animation complete.');
    //return false;
});

HTML

<a id="gotop" href="#">Go Top </a>

CSS

#gotop {
      cursor: pointer;
      position: relative;
      float: right;
      right: 20px;
      /*top:0px;*/
}
Floats answered 15/6, 2010 at 5:8 Comment(5)
jsbin.com/erade/2 works fine on chromeLaquitalar
@jAndy, I was wondering why scrollTop, which is not a valid css property, works on your demo?... can you share some info or link about it?Diaphoresis
@Reigel: I have to admit, I can't. I use it pretty much like a blackbox, but jQuery infact normalizes it crossbrowser.Laquitalar
@Laquitalar - okay... but I guess it would not be advisable to use scrollTop inside animate css map properties... I'm still digging though..Diaphoresis
Possible duplicate of scrolltop with animate not workingErythroblastosis
T
106

Try using $("html,body").animate({ scrollTop: 0 }, "slow");

This works for me in chrome.

Teirtza answered 15/6, 2010 at 6:4 Comment(9)
Yes.Thanks.Simple and timesaving.Floats
I had exactly the same issue, although I was also animating scrollTop. the interesting thing is that $("html") works in FF, and $("body") works in Chrome/Safari, but only $("html,body") has worked for me in both.Tenfold
This has a side effect: a callback function will be called twice (once for each element). Any smart workaround for this, anybody?Stump
Put: if (this.nodeName == "BODY") { return; } at the beginning of your callback function so only the callback from the html element will go through. Also, remember that the nodeName attribute on html elements is always uppercase.Bello
Thank you @Bello for pointing this out! Extremely useful when using a callback function that one should fire once and work across all browsers! TA!Chianti
The bad side of this is that in Firefox, the callback method of animate will be called twice. Once for body and than for html :/Kistner
I had to use $("body,html") to work in all browsers.Aloysius
Sorry but I can't get it working in Chrome, I just want speed when scroll, do not execute anythig else, so I just put jQuery.scrollSpeed(100, 800); when "document ready", What do I have to do for working with chorme? ThanksAvelin
Just to add, than I have scroll on a div inside body, not in bodyAvelin
B
58

If your CSS html element has the following overflow markup, scrollTop will not function.

html {
    overflow-x: hidden;
    overflow-y: hidden;
}

To allow scrollTop to scroll, modify your markup remove overflow markup from the html element and append to a body element.

body { 
    overflow-x: hidden;
    overflow-y: hidden;
}
Border answered 6/11, 2014 at 3:23 Comment(6)
it maybe more than 4 years old, but it was still the solution to my problemDagenham
@Leandro this is the solution in chrome 41. don't discourage an answer that answers the question.Hissing
@Leandro This guy just saved my life! it worked for meMegaspore
oh my god this solved TWO problems for me. Many many thanks <3Triumvirate
I... spent over 5 hours trying to figure out why it wasn't working. Thank you so much for this!Belongings
can someone please explain why does it work, it solved my problem as well but I don't understand why.Parget
G
15

It works in both browsers if you use scrollTop() with 'document':

$(document).scrollTop();

...instead of 'html' or 'body'. Other way it won't work at the same time in both browsers.

Grozny answered 22/3, 2012 at 10:3 Comment(1)
document worked for me when 'html' and 'body' didn't. Thanks :)Decastro
M
5

I have used this with success in Chrome, Firefox, and Safari. Haven't been able to test it in IE yet.

if($(document).scrollTop() !=0){
    $('html, body').animate({ scrollTop: 0 }, 'fast');
}

The reason for the "if" statement is to check if the user is all ready at the top of the site. If so, don't do the animation. That way we don't have to worry so much about screen resolution.

The reason I use $(document).scrollTop instead of ie. $('html,body') is cause Chrome always return 0 for some reason.

Mindoro answered 4/5, 2011 at 19:15 Comment(0)
B
4

I had a same problem with scrolling in chrome. So i removed this lines of codes from my style file.

html{height:100%;}
body{height:100%;}

Now i can play with scroll and it works:

var pos = 500;
$("html,body").animate({ scrollTop: pos }, "slow");
Brunildabruning answered 15/8, 2016 at 6:3 Comment(2)
Wow. This totally fixed my issue! I could not get scrollTop to work at all but once i removed height: 100% from the body and html element it worked great. Thank you, thank you, thank you.Malacology
@agon024, I'm happy too ;) . Really i founded this solution after several hours test and try and wrote here for some one like you.Brunildabruning
J
2

Scroll body and check if it worked:

function getScrollableRoot() {
    var body = document.body;
    var prev = body.scrollTop;
    body.scrollTop++;
    if (body.scrollTop === prev) {
        return document.documentElement;
    } else {
        body.scrollTop--;
        return body;
    }
}


$(getScrollableRoot()).animate({ scrollTop: 0 }, "slow");

This is more efficient than $("html, body").animate because only one animation used, not two. Thus, only one callback fires, not two.

Jerk answered 10/9, 2013 at 6:49 Comment(1)
Nice job! Helped me a lot!Aiglet
D
1

maybe you mean top: 0

$('a#gotop').click(function() {
  $("html").animate({ top: 0 }, "slow", function() { 
                                           alert('Animation complete.'); });
  //return false;
});

from animate docs

.animate( properties, [ duration ], [ easing ], [ callback ] )
properties A map of CSS properties that the animation will move toward.
...

or $(window).scrollTop() ?

$('a#gotop').click(function() {
  $("html").animate({ top: $(window).scrollTop() }, "slow", function() { 
                                                              alert('Animation complete.'); });
  //return false;
});
Diaphoresis answered 15/6, 2010 at 5:16 Comment(1)
still the animation is not working. Found simple solution.I had to use "body,html" or "html,body" instead of just "html".Floats
D
1
// if we are not already in top then see if browser needs html or body as selector
var obj = $('html').scrollTop() !== 0 ? 'html' : 'body';

// then proper delegate using on, with following line:
$(obj).animate({ scrollTop: 0 }, "slow");

BUT, best approach is to scroll an id into your viewport using just native api (since you scroll to top anyway this can be just your outer div):

document.getElementById('wrapperIDhere').scrollIntoView(true);
Dialogize answered 27/9, 2012 at 20:4 Comment(1)
This best approach bypasses the issue with overflow-x: hidden; on html in chrome. However it doesn't smooth scroll like .animate() does.Passage
K
1

I use:

var $scrollEl = $.browser.mozilla ? $('html') : $('body');

because read jQuery scrollTop not working in Chrome but working in Firefox

Kistner answered 10/5, 2013 at 16:30 Comment(0)
C
0

A better way to solve this problem is to use a function like this:

function scrollToTop(callback, q) {

    if ($('html').scrollTop()) {
        $('html').animate({ scrollTop: 0 }, function() {
            console.log('html scroll');
            callback(q)
        });
        return;
    }

    if ($('body').scrollTop()) {
        $('body').animate({ scrollTop: 0 }, function() {
            console.log('body scroll');
            callback(q)
        });
        return;
    }

    callback(q);
}

This will work across all browsers and prevents FireFox from scrolling up twice (which is what happens if you use the accepted answer - $("html,body").animate({ scrollTop: 0 }, "slow");).

Cloudland answered 10/3, 2016 at 12:25 Comment(0)
W
0

Testing on Chrome, Firefox and Edge, the only solution that worked fine for me is using setTimeout with the solution of Aaron in this way:

setTimeout( function () {
    $('body, html').stop().animate({ scrollTop: 0 }, 100);
}, 500);

No one of the other solutions resetted the previuos scrollTop, when I reloaded the page, in Chrome and Edge for me. Unfortunately there is still a little "flick" in Edge.

Worl answered 30/6, 2016 at 10:12 Comment(0)
W
0

So I was having this problem too and I have written this function:

/***Working function for ajax loading Start*****************/
function fuweco_loadMoreContent(elmId/*element ID without #*/,ajaxLink/*php file path*/,postParameterObject/*post parameters list as JS object with properties (new Object())*/,tillElementEnd/*point of scroll when must be started loading from AJAX*/){
	var	
		contener = $("#"+elmId),
		contenerJS = document.getElementById(elmId);
	if(contener.length !== 0){
		var	
			elmFullHeight = 
				contener.height()+
				parseInt(contener.css("padding-top").slice(0,-2))+
				parseInt(contener.css("padding-bottom").slice(0,-2)),
			SC_scrollTop = contenerJS.scrollTop,
			SC_max_scrollHeight = contenerJS.scrollHeight-elmFullHeight;
		if(SC_scrollTop >= SC_max_scrollHeight - tillElementEnd){
			$("#"+elmId).unbind("scroll");
			$.post(ajaxLink,postParameterObject)
			 .done(function(data){
			 	if(data.length != 0){
					$("#"+elmId).append(data);
					$("#"+elmId).scroll(function (){
						fuweco_reloaderMore(elmId,ajaxLink,postParameterObject);
					});
				}
			 });
		}
	}
}
/***Working function for ajax loading End*******************/
/***Sample function Start***********************************/
function reloaderMore(elementId) {
	var
		contener = $("#"+elementId),
		contenerJS = document.getElementById(elementId)
	;

    if(contener.length !== 0){
    	var
			elmFullHeight = contener.height()+(parseInt(contener.css("padding-top").slice(0,-2))+parseInt(contener.css("padding-bottom").slice(0,-2))),
			SC_scrollTop = contenerJS.scrollTop,
			SC_max_scrollHeight = contenerJS.scrollHeight-elmFullHeight
		;
		if(SC_scrollTop >= SC_max_scrollHeight - 200){
			$("#"+elementId).unbind("scroll");
			$("#"+elementId).append('<div id="elm1" style="margin-bottom:15px;"><h1>Was loaded</h1><p>Some text for content. Some text for content. Some text for content.	Some text for content. Some text for content. Some text for content. Some text for content. Some text for content. Some text for content. Some text for content. Some text for content. Some text for content.</p></div>');
			$("#"+elementId).delay(300).scroll(function (){reloaderMore(elementId);});
		}
    }
}
/***Sample function End*************************************/
/***Sample function Use Start*******************************/
$(document).ready(function(){
	$("#t1").scrollTop(0).scroll(function (){
		reloaderMore("t1");
    });
});
/***Sample function Use End*********************************/
.reloader {
    border: solid 1px red;
    overflow: auto;
    overflow-x: hidden;
    min-height: 400px;
    max-height: 400px;
    min-width: 400px;
    max-width: 400px;
    height: 400px;
    width: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
	<div class="reloader" id="t1">
		<div id="elm1" style="margin-bottom:15px;">
			<h1>Some text for header.</h1>
			<p>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
			</p>
		</div>
		<div id="elm2" style="margin-bottom:15px;">
			<h1>Some text for header.</h1>
			<p>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
			</p>
		</div>
		<div id="elm3" style="margin-bottom:15px;">
			<h1>Some text for header.</h1>
			<p>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
				Some text for content.<br>
			</p>
		</div>		
	</div>

I hope it will be helpfully for other programmers.

Whorl answered 28/7, 2016 at 9:12 Comment(0)
M
0

If it work all fine for Mozilla, with html,body selector, then there is a good chance that the problem is related to the overflow, if the overflow in html or body is set to auto, then this will cause chrome to not work well, cause when it is set to auto, scrollTop property on animate will not work, i don't know exactly why! but the solution is to omit the overflow, don't set it! that solved it for me! if you are setting it to auto, take it off!

if you are setting it to hidden, then do as it is described in "user2971963" answer (ctrl+f to find it). hope this is useful!

Madonia answered 19/5, 2017 at 10:36 Comment(0)
T
0
 $("html, body").animate({ scrollTop: 0 }, "slow");

This CSS conflict with scroll to top so take care of this

 html, body {
         overflow-x: hidden;        
    }
Topmost answered 15/9, 2017 at 7:0 Comment(0)
L
0

I found that my CSS was the issue. I removed this from my style sheet and it worked fine.

*{scroll-behavior: smooth;}
Larcener answered 22/6, 2021 at 9:12 Comment(0)
C
-3

I don't think the scrollTop is a valid property. If you want to animate scrolling, try the scrollTo plugin for jquery

http://plugins.jquery.com/project/ScrollTo

Critta answered 15/6, 2010 at 5:13 Comment(4)
When did I say scrollTop() is a property? You don't need to use a plugin as this function is already implemented in jQuery.Pathos
@Bayan - your deleted answer would have answer When did I say scrollTop() is a property? and besides, the OP want a smooth animation, can scrollTop() do smooth?... and it's worth noting that Ben's answer above clearly state, I don't think the scrollTop is a valid property and you commented as scrollTop() is valid jQuery...Diaphoresis
@Floats fair enough. Glad to see you got your problem sorted however :)Critta
@Reigel ScrollTop does smooth just fine: jsfiddle.net/JohnnyWalkerDesign/w4hetv45Cloudland

© 2022 - 2024 — McMap. All rights reserved.