jQuery scrollTop no funciona en Chrome pero funciona en Firefox

80

He usado una scrollTopfunción en jQuery para navegar hacia arriba, pero extrañamente 'el desplazamiento animado suave' dejó de funcionar en Safari y Chrome (desplazamiento sin animación suave) después de que hice algunos cambios.

Pero todavía funciona sin problemas en Firefox. ¿Qué podría estar mal?

Aquí está la función jQuery que usé,

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;*/
}
Maju
fuente
1
jsbin.com/erade/2 funciona bien en Chrome
jAndy
@jAndy, me preguntaba por qué scrollTop, que no es una propiedad css válida, funciona en su demostración ... ¿puede compartir información o un enlace al respecto?
Reigel
@Reigel: Tengo que admitir que no puedo. Lo uso más o menos como una caja negra, pero jQuery de hecho lo normaliza en el navegador cruzado.
jAndy
@jAndy - está bien ... pero supongo que no sería aconsejable usar scrollTopdentro de las propiedades del mapa CSS animado ... Aunque todavía estoy investigando ..
Reigel
Posible duplicado de scrolltop con animate no funciona
Mister Q

Respuestas:

106

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

Esto me funciona en Chrome.

Aaron Harun
fuente
Sí, gracias, sencillo y ahorra tiempo.
Maju
3
Esto tiene un efecto secundario: se llamará dos veces a una función de devolución de llamada (una para cada elemento). ¿Alguna solución inteligente para esto, alguien?
bububaba
8
Ponga: if (this.nodeName == "BODY") {return; } al comienzo de la función de devolución de llamada, por lo que solo se realizará la devolución de llamada del elemento html. Además, recuerde que el atributo nodeName en los elementos html siempre está en mayúsculas.
Bobby
1
¡Gracias @Bobby por señalar esto! ¡Extremadamente útil cuando se usa una función de devolución de llamada que se debe activar una vez y funcionar en todos los navegadores! ¡EJÉRCITO DE RESERVA!
Sebastian
1
Tuve que usar $ ("body, html") para trabajar en todos los navegadores.
Tom Kincaid
57

Si su htmlelemento CSS tiene el siguiente overflowmarcado, scrollTopno funcionará.

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

Para permitir el scrollTopdesplazamiento, modifique su marcado, elimine el overflowmarcado del htmlelemento y añádalo a un bodyelemento.

body { 
    overflow-x: hidden;
    overflow-y: hidden;
}
usuario2971963
fuente
4
Es tal vez más de 4 años de edad, pero todavía era la solución a mi problema
Rafael Rotelok
1
@Leandro esta es la solución en chrome 41. no desanimes una respuesta que responda a la pregunta.
Trabajo
1
@Leandro ¡Este tipo me acaba de salvar la vida! funcionó para mí
liltof
Dios mío, esto me resolvió DOS problemas. Muchas, muchas gracias <3
Osamah Aldoaiss
Pasé más de 5 horas tratando de averiguar por qué no funcionaba. muchas gracias por esto!
PepperAddict
15

Funciona en ambos navegadores si usa scrollTop () con 'documento':

$(document).scrollTop();

... en lugar de 'html' o 'cuerpo'. De lo contrario, no funcionará al mismo tiempo en ambos navegadores.

Alejandro del Río
fuente
el documento funcionó para mí cuando 'html' y 'body' no lo hicieron. Gracias :)
ConorLuddy
5

Lo he usado con éxito en Chrome, Firefox y Safari. Todavía no he podido probarlo en IE.

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

El motivo de la declaración "si" es comprobar si el usuario está listo en la parte superior del sitio. Si es así, no hagas la animación. De esa forma no tendremos que preocuparnos tanto por la resolución de la pantalla.

La razón por la que uso en $(document).scrollToplugar de ie. $('html,body')es porque Chrome siempre devuelve 0 por alguna razón.

Steven
fuente
3

Tuve el mismo problema con el desplazamiento en cromo. Así que eliminé estas líneas de códigos de mi archivo de estilo.

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

Ahora puedo jugar con scroll y funciona:

var pos = 500;
$("html,body").animate({ scrollTop: pos }, "slow");
RAM
fuente
Guau. ¡Esto solucionó totalmente mi problema! No pude hacer que scrollTop funcionara en absoluto, pero una vez que eliminé la altura: 100% del cuerpo y el elemento html, funcionó muy bien. Gracias, gracias, gracias.
agon024
@ agon024, yo también estoy feliz;). Realmente fundé esta solución después de varias horas de prueba e intenté escribir aquí para alguien como tú.
RAM
2

Desplácese por el cuerpo y compruebe si funcionó:

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

Esto es más eficiente que $("html, body").animateporque solo se usa una animación, no dos. Por lo tanto, solo se activa una devolución de llamada, no dos.

NVI
fuente
¡Buen trabajo! ¡Me ayudo mucho!
gogachinchaladze
1

tal vez te refieres top: 0

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

de documentos animados

.animate ( propiedades , [duración], [suavizado], [devolución de llamada])
propiedades Un mapa de propiedades CSS hacia el que se moverá la animación.
...

o $(window).scrollTop()?

$('a#gotop').click(function() {
  $("html").animate({ top: $(window).scrollTop() }, "slow", function() { 
                                                              alert('Animation complete.'); });
  //return false;
});
Reigel
fuente
aún la animación no funciona. Encontré una solución simple. Tuve que usar "body, html" o "html, body" en lugar de solo "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");

PERO, el mejor enfoque es desplazar una identificación en su ventana gráfica usando solo una API nativa (ya que se desplaza hacia la parte superior de todos modos, esto puede ser solo su div exterior):

document.getElementById('wrapperIDhere').scrollIntoView(true);
Maar10
fuente
Este mejor enfoque evita el problema con overflow-x: hidden;encendido htmlen Chrome. Sin embargo, no suaviza el desplazamiento como lo .animate()hace.
Jimmy
0

Una mejor manera de resolver este problema es usar una función como esta:

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

Esto funcionará en todos los navegadores y evitará que FireFox se desplace hacia arriba dos veces (que es lo que sucede si usa la respuesta aceptada - $("html,body").animate({ scrollTop: 0 }, "slow");).

Chuck Le Butt
fuente
0

Probando en Chrome, Firefox y Edge, la única solución que funcionó bien para mí es usar setTimeout con la solución de Aaron de esta manera:

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

Ninguna de las otras soluciones restableció el scrollTop anterior, cuando recargué la página, en Chrome y Edge por mí. Desafortunadamente, todavía hay un pequeño "movimiento" en Edge.

Cerveza inglesa
fuente
0

Entonces yo también estaba teniendo este problema y escribí esta función:

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

Espero que sea útil para otros programadores.

Vladimir A.
fuente
0

Si todo funciona bien para Mozilla, con html, selector de cuerpo, entonces hay una buena posibilidad de que el problema esté relacionado con el desbordamiento, si el desbordamiento en html o en el cuerpo está configurado en automático, entonces esto hará que Chrome no funcione bien , porque cuando está configurado en automático, la propiedad scrollTop en animate no funcionará, ¡no sé exactamente por qué! pero la solución es omitir el desbordamiento, ¡no lo configure! eso me lo solucionó! si lo está configurando en automático, ¡quítelo!

si lo configura como oculto, haga lo que se describe en la respuesta "user2971963" (ctrl + f para encontrarlo). espero que esto sea útil!

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

Este CSS entra en conflicto con el desplazamiento hacia la parte superior, así que ocúpate de esto.

 html, body {
         overflow-x: hidden;        
    }
Ashutosh Jha
fuente
-3

No creo que scrollTop sea una propiedad válida. Si desea animar el desplazamiento, pruebe el complemento scrollTo para jquery

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

Ben Rowe
fuente
¿Cuándo dije scrollTop () es una propiedad? No necesita usar un complemento ya que esta función ya está implementada en jQuery.
Bayard Randel
@Bayan: su respuesta eliminada tendría respuesta When did I say scrollTop() is a property?y, además, el OP quiere una animación suave, ¿puede scrollTop()hacerlo sin problemas? ... y vale la pena señalar que la respuesta de Ben anterior indica claramente, I don't think the scrollTop is a valid propertyy usted comentó como scrollTop() is valid jQuery...
Reigel
1
@Maju lo suficientemente justo. Sin embargo, me alegra ver que resolvió su problema :)
Ben Rowe
@Reigel lo ScrollTophace bien: jsfiddle.net/JohnnyWalkerDesign/w4hetv45
Chuck Le Butt