jQuery scrollTop funktioniert nicht in Chrome, sondern in Firefox


80

Ich habe eine scrollTopFunktion in jQuery verwendet, um nach oben zu navigieren, aber seltsamerweise funktionierte "die glatte animierte Schriftrolle" in Safari und Chrome (Scrollen ohne glatte Animation) nicht mehr, nachdem ich einige Änderungen vorgenommen hatte.

Aber es funktioniert immer noch reibungslos in Firefox. Was könnte falsch sein?

Hier ist die von mir verwendete jQuery-Funktion:

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 funktioniert gut auf Chrom
jAndy

@jAndy, ich habe mich gefragt, warum scrollTop, was keine gültige CSS-Eigenschaft ist, an Ihrer Demo funktioniert? ... können Sie einige Informationen oder Links dazu teilen?
Reigel

@Reigel: Ich muss zugeben, ich kann nicht. Ich benutze es ziemlich ähnlich wie eine Blackbox, aber jQuery infact normalisiert es als Crossbrowser.
jAndy

@jAndy - okay ... aber ich denke, es wäre nicht ratsam, scrollTopin animierten CSS-Map-Eigenschaften zu verwenden ... Ich grabe immer noch ..
Reigel

Antworten:


106

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

Das funktioniert bei mir in Chrom.


Ja. Danke. Einfach und zeitsparend.
Maju

3
Dies hat einen Nebeneffekt: Eine Rückruffunktion wird zweimal aufgerufen (einmal für jedes Element). Gibt es dafür eine clevere Problemumgehung?
Bububaba

8
Put: if (this.nodeName == "BODY") {return; } am Anfang Ihrer Rückruffunktion, sodass nur der Rückruf vom HTML-Element durchlaufen wird. Denken Sie auch daran, dass das Attribut nodeName für HTML-Elemente immer in Großbuchstaben geschrieben ist.
Bobby

1
Vielen Dank an @Bobby für diesen Hinweis! Sehr nützlich bei Verwendung einer Rückruffunktion, die einmal ausgelöst und in allen Browsern verwendet werden sollte! TA!
Sebastian

1
Ich musste $ ("body, html") verwenden, um in allen Browsern zu arbeiten.
Tom Kincaid

57

Wenn Ihr CSS- htmlElement das folgende overflowMarkup aufweist, scrollTopfunktioniert es nicht.

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

Um einen scrollTopBildlauf zu ermöglichen , ändern Sie Ihr Markup, entfernen Sie das overflowMarkup aus dem htmlElement und hängen Sie es an ein bodyElement an.

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

4
es ist vielleicht älter als 4 Jahre, aber es war immer noch die Lösung für mein Problem
Rafael Rotelok

1
@Leandro Dies ist die Lösung in Chrome 41. Entmutigen Sie nicht eine Antwort, die die Frage beantwortet.
Worc

1
@Leandro Dieser Typ hat mir gerade das Leben gerettet! es hat bei mir
funktioniert

Oh mein Gott, das hat ZWEI Probleme für mich gelöst. Vielen vielen Dank <3
Osamah Aldoaiss

Ich ... habe über 5 Stunden damit verbracht herauszufinden, warum es nicht funktioniert hat. Vielen Dank dafür!
PepperAddict

15

Es funktioniert in beiden Browsern, wenn Sie scrollTop () mit 'document' verwenden:

$(document).scrollTop();

... anstelle von 'html' oder 'body'. Andernfalls funktioniert es nicht in beiden Browsern gleichzeitig.


Dokument funktionierte für mich, als 'HTML' und 'Körper' nicht. Danke :)
ConorLuddy

5

Ich habe dies mit Erfolg in Chrome, Firefox und Safari verwendet. Ich konnte es noch nicht im IE testen.

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

Der Grund für die "if" -Anweisung besteht darin, zu überprüfen, ob der Benutzer oben auf der Site bereit ist. Wenn ja, machen Sie die Animation nicht. Auf diese Weise müssen wir uns nicht so viele Sorgen um die Bildschirmauflösung machen.

Der Grund, den ich $(document).scrollTopanstelle von dh benutze . $('html,body')Dies liegt daran, dass Chrome aus irgendeinem Grund immer 0 zurückgibt.


2

Scrollen Sie den Körper und prüfen Sie, ob er funktioniert hat:

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

Dies ist effizienter als $("html, body").animateweil nur eine Animation verwendet wird, nicht zwei. Somit wird nur ein Rückruf ausgelöst, nicht zwei.


Gute Arbeit! Hat mir viel geholfen!
Gogachinchaladze

2

Ich hatte das gleiche Problem beim Scrollen in Chrom. Also habe ich entfernt diese Zeilen von Codes aus meiner Stildatei.

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

Jetzt kann ich mit Scroll spielen und es funktioniert:

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

Beeindruckend. Das hat mein Problem total behoben! Ich konnte scrollTop überhaupt nicht zum Laufen bringen, aber als ich die Höhe entfernt hatte: 100% vom Körper und dem HTML-Element, funktionierte es großartig. Danke danke danke.
agon024

@ agon024, ich bin auch glücklich;). Wirklich, ich habe diese Lösung nach mehreren Stunden Test gegründet und versucht, hier für jemanden wie Sie zu schreiben.
RAM

1

Vielleicht meinst du top: 0

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

aus animierten Dokumenten

.animate ( Eigenschaften , [Dauer], [Beschleunigung], [Rückruf])
Eigenschaften Eine Karte der CSS-Eigenschaften, auf die sich die Animation bewegt.
...

oder $(window).scrollTop()?

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

Die Animation funktioniert immer noch nicht. Einfache Lösung gefunden. Ich musste "body, html" oder "html, body" anstelle von nur "html" verwenden.
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");

ABER der beste Ansatz ist, eine ID mit nur nativer API in Ihr Ansichtsfenster zu scrollen (da Sie sowieso nach oben scrollen, kann dies nur Ihr äußerer Teil sein):

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

Dieser beste Ansatz umgeht das Problem mit overflow-x: hidden;on htmlin Chrome. Es glättet jedoch nicht wie .animate()dies.
Jimmy


0

Eine bessere Möglichkeit, dieses Problem zu lösen, besteht darin, eine Funktion wie die folgende zu verwenden:

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

Dies funktioniert in allen Browsern und verhindert, dass FireFox zweimal nach oben scrollt (was passiert, wenn Sie die akzeptierte Antwort verwenden - $("html,body").animate({ scrollTop: 0 }, "slow");).


0

Beim Testen auf Chrome, Firefox und Edge hat setTimeout mit der Lösung von Aaron auf folgende Weise funktioniert:

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

Keine der anderen Lösungen hat das vorherige scrollTop beim erneuten Laden der Seite in Chrome und Edge für mich zurückgesetzt. Leider gibt es in Edge noch einen kleinen "Flick".


0

Also hatte ich auch dieses Problem und habe diese Funktion geschrieben:

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

Ich hoffe, es wird für andere Programmierer hilfreich sein.


0

Wenn es für Mozilla mit HTML, Body Selector, einwandfrei funktioniert, besteht eine gute Chance, dass das Problem mit dem Überlauf zusammenhängt. Wenn der Überlauf in HTML oder Body auf Auto eingestellt ist, funktioniert Chrome nicht richtig , weil, wenn es auf auto gesetzt ist, die scrollTop-Eigenschaft beim Animieren nicht funktioniert, ich weiß nicht genau warum! Aber die Lösung besteht darin, den Überlauf wegzulassen, nicht einzustellen! das hat es für mich gelöst! Wenn Sie es auf Auto einstellen, nehmen Sie es ab!

Wenn Sie es auf versteckt setzen, gehen Sie wie in der Antwort "user2971963" beschrieben vor (Strg + f, um es zu finden). hoffe das ist nützlich!


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

Dieser CSS-Konflikt mit dem Bildlauf nach oben

 html, body {
         overflow-x: hidden;        
    }

-3

Ich denke nicht, dass das scrollTop eine gültige Eigenschaft ist. Wenn Sie das Scrollen animieren möchten, versuchen Sie es mit dem scrollTo-Plugin für jquery

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


Wann habe ich gesagt, dass scrollTop () eine Eigenschaft ist? Sie müssen kein Plugin verwenden, da diese Funktion bereits in jQuery implementiert ist.
Bayard Randel

@Bayan - Ihre gelöschte Antwort hätte eine Antwort When did I say scrollTop() is a property?und außerdem möchte das OP eine reibungslose Animation, kann scrollTop()reibungslos funktionieren? ... und es ist erwähnenswert, dass Bens Antwort oben eindeutig besagt, I don't think the scrollTop is a valid propertyund Sie kommentierten als scrollTop() is valid jQuery...
Reigel

1
@Maju fair genug. Ich bin froh zu sehen, dass du dein Problem gelöst hast :)
Ben Rowe

@Reigel ScrollTopmacht alles gut: jsfiddle.net/JohnnyWalkerDesign/w4hetv45
Chuck Le Butt
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.