jQuery scrollTop nie działa w przeglądarce Chrome, ale działa w przeglądarce Firefox


80

Użyłem scrollTopfunkcji w jQuery do przechodzenia na górę, ale dziwnie „płynne animowane przewijanie” przestało działać w Safari i Chrome (przewijanie bez płynnej animacji) po wprowadzeniu pewnych zmian.

Ale nadal działa płynnie w Firefoksie. Co może być nie tak?

Oto funkcja jQuery, której użyłem,

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;*/
}

1
jsbin.com/erade/2 działa dobrze na chrome
jAndy

@jAndy, zastanawiałem się, dlaczego scrollTop, co nie jest prawidłową właściwością css, działa na twoim demo? ... czy możesz udostępnić jakieś informacje lub link na ten temat?
Reigel

@Reigel: Muszę przyznać, że nie mogę. Używam go prawie jak czarnej skrzynki, ale jQuery w rzeczywistości normalizuje go w różnych przeglądarkach.
jAndy

@jAndy - ok ... ale wydaje mi się, że nie byłoby wskazane używanie scrollTopwewnątrz animowanych właściwości mapy css ... Jednak nadal
kopie

Odpowiedzi:


106

Spróbuj użyć $("html,body").animate({ scrollTop: 0 }, "slow");

To działa dla mnie w chrome.


Tak, dzięki, to proste i oszczędne.
Maju

3
Ma to efekt uboczny: funkcja zwrotna zostanie wywołana dwukrotnie (raz dla każdego elementu). Czy ktoś może mądrze obejść ten problem?
bububaba

8
Umieść: if (this.nodeName == "BODY") {return; } na początku Twojej funkcji zwrotnej, więc tylko wywołanie zwrotne z elementu html będzie przechodziło. Pamiętaj też, że atrybut nodeName w elementach html jest zawsze pisany wielkimi literami.
Bobby

1
Dziękuję @Bobby za wskazanie tego! Niezwykle przydatne podczas korzystania z funkcji wywołania zwrotnego, którą należy uruchomić raz i działać we wszystkich przeglądarkach! TA!
Sebastian,

1
Musiałem używać $ („body, html”), aby działać we wszystkich przeglądarkach.
Tom Kincaid,

57

Jeśli Twój htmlelement CSS ma następujące overflowznaczniki, scrollTopnie będzie działać.

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

Aby umożliwić scrollTopprzewijanie, zmodyfikuj swój znacznik, usuń overflowznacznik z htmlelementu i dołącz do bodyelementu.

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

4
może ma więcej niż 4 lata, ale nadal było rozwiązaniem mojego problemu
Rafael Rotelok

1
@Leandro to jest rozwiązanie w chrome 41. nie zniechęcaj odpowiedzi, która odpowiada na pytanie.
worc

1
@Leandro Ten facet właśnie uratował mi życie! zadziałało dla mnie
liltof

o mój Boże, to rozwiązało dla mnie DWA problemy. Wielkie dzięki <3
Osamah Aldoaiss

Spędziłem ... ponad 5 godzin, próbując dowiedzieć się, dlaczego to nie działa. Dziękuję bardzo za to!
PepperAddict

15

Działa w obu przeglądarkach, jeśli używasz scrollTop () z 'dokumentem':

$(document).scrollTop();

... zamiast „html” lub „body”. W przeciwnym razie nie będzie działać jednocześnie w obu przeglądarkach.


dokument działał u mnie, gdy „html” i „body” nie. Dzięki :)
ConorLuddy

5

Użyłem tego z powodzeniem w Chrome, Firefox i Safari. Nie udało mi się jeszcze przetestować tego w IE.

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

Powodem użycia instrukcji „if” jest sprawdzenie, czy użytkownik jest gotowy na górze strony. Jeśli tak, nie rób animacji. W ten sposób nie musimy martwić się zbytnio o rozdzielczość ekranu.

Powód, dla którego używam $(document).scrollTopzamiast tj. $('html,body')z jakiegoś powodu Chrome zawsze zwraca 0.


3

Miałem ten sam problem z przewijaniem w chrome. Więc usunąłem te linie kodów z mojego pliku stylu.

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

Teraz mogę bawić się scrollem i działa:

var pos = 500;
$("html,body").animate({ scrollTop: pos }, "slow");

Łał. To całkowicie rozwiązało mój problem! W ogóle nie mogłem zmusić scrollTop do działania, ale po usunięciu wysokości: 100% z body i elementu html działało świetnie. Dziekuję Dziekuję Dziękuję.
agon024,

@ agon024, ja też jestem szczęśliwy;). Naprawdę założyłem to rozwiązanie po kilku godzinach testów i spróbuję napisać tutaj dla kogoś takiego jak Ty.
RAM

2

Przewiń treść i sprawdź, czy zadziałało:

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");

Jest to bardziej wydajne niż $("html, body").animateużycie tylko jednej animacji, a nie dwóch. Zatem tylko jedno wywołanie zwrotne jest uruchamiane, a nie dwa.


Dobra robota! Bardzo mi pomogło!
gogachinchaladze

1

może masz na myśli top: 0

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

od animowanych dokumentów

.animate ( properties , [duration], [easing], [callback])
properties Mapa właściwości CSS, w kierunku których będzie się poruszać animacja.
...

czy $(window).scrollTop()?

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

nadal animacja nie działa. Znalazłem proste rozwiązanie. Musiałem użyć „body, html” lub „html, body” zamiast tylko „html”.
Maju

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");

ALE najlepszym podejściem jest przewinięcie identyfikatora do widoku za pomocą samego natywnego interfejsu API (ponieważ i tak przewijasz do góry, może to być tylko zewnętrzny element div):

document.getElementById('wrapperIDhere').scrollIntoView(true);

To najlepsze podejście pozwala obejść problem z overflow-x: hidden;włączeniem htmlw przeglądarce Chrome. Jednak nie wygładza przewijania, jak to .animate()robi.
Jimmy,


0

Lepszym sposobem rozwiązania tego problemu jest użycie takiej funkcji:

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);
}

Będzie to działać we wszystkich przeglądarkach i zapobiegnie dwukrotnemu przewinięciu FireFox w górę (co się stanie, jeśli użyjesz zaakceptowanej odpowiedzi - $("html,body").animate({ scrollTop: 0 }, "slow");).


0

Testując na Chrome, Firefox i Edge jedynym rozwiązaniem, które działało dobrze, jest użycie setTimeout z rozwiązaniem Aarona w ten sposób:

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

Żadne z innych rozwiązań nie zresetowało poprzedniego scrollTop, kiedy ponownie załadowałem stronę, w Chrome i Edge dla mnie. Niestety w Edge wciąż jest mały „flick”.


0

Więc też miałem ten problem i napisałem tę funkcję:

/***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>

Mam nadzieję, że będzie to pomocne dla innych programistów.


0

Jeśli wszystko działa dobrze dla Mozilli, z html, selektorem ciała, to jest duża szansa, że ​​problem jest związany z przepełnieniem, jeśli przepełnienie w html lub body jest ustawione na auto, to spowoduje to, że chrome nie będzie działał dobrze , ponieważ gdy jest ustawione na auto, właściwość scrollTop na animate nie będzie działać, nie wiem dokładnie dlaczego! ale rozwiązaniem jest pominięcie przepełnienia, nie ustawiaj go! rozwiązało to dla mnie! jeśli ustawiasz go na auto, zdejmij go!

jeśli ustawiasz go jako ukryty, zrób to, co jest opisane w odpowiedzi "user2971963" (ctrl + f, aby go znaleźć). mam nadzieję, że to się przyda!


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

Ten konflikt CSS z przewijaniem do góry, więc zajmij się tym

 html, body {
         overflow-x: hidden;        
    }

-3

Nie sądzę, że scrollTop jest prawidłową właściwością. Jeśli chcesz animować przewijanie, wypróbuj wtyczkę scrollTo do jquery

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


Kiedy powiedziałem, że scrollTop () jest właściwością? Nie musisz używać wtyczki, ponieważ ta funkcja jest już zaimplementowana w jQuery.
Bayard Randel

@Bayan - twoja usunięta odpowiedź miałaby odpowiedź, When did I say scrollTop() is a property?a poza tym OP chce płynnej animacji, może scrollTop()zrobić płynną? ... i warto zauważyć, że powyższa odpowiedź Bena wyraźnie stwierdza, I don't think the scrollTop is a valid propertya skomentowałeś jako scrollTop() is valid jQuery...
Reigel

1
@ Maju fair. Cieszę się, że udało Ci się rozwiązać problem :)
Ben Rowe

@Reigel ScrollToprobi gładko dobrze: jsfiddle.net/JohnnyWalkerDesign/w4hetv45
Chuck Le Butt
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.