web-dev-qa-db-fra.com

jQuery scrollTop ne fonctionne pas dans Chrome mais fonctionne dans Firefox

J'ai utilisé une fonction scrollTop dans jQuery pour naviguer vers le haut, mais étrangement, "le défilement animé fluide" a cessé de fonctionner dans Safari et Chrome (défilement sans animation fluide) après quelques modifications. 

Mais cela fonctionne toujours bien dans Firefox. Quel pourrait être le problème?

Voici la fonction jQuery que j'ai utilisée,

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

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

Cela fonctionne pour moi en chrome.

99
Aaron Harun

Si votre élément CSS html a le balisage overflow suivant, scrollTop ne fonctionnera pas.

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

Pour permettre au scrollTop de défiler, modifiez votre balisage, supprimez le balisage overflow de l'élément html et ajoutez-le à un élément body

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

Cela fonctionne dans les deux navigateurs si vous utilisez scrollTop () avec 'document':

$(document).scrollTop();

... au lieu de 'html' ou 'body'. Autrement, cela ne fonctionnera pas en même temps dans les deux navigateurs.

14
Alejandro del Río

J'ai utilisé cela avec succès dans Chrome, Firefox et Safari. Je n'ai pas encore été en mesure de le tester dans IE.

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

La raison de l'instruction "if" est de vérifier si l'utilisateur est tout prêt en haut du site. Si c'est le cas, ne faites pas l'animation. De cette façon, nous n'avons pas à nous préoccuper autant de la résolution de l'écran.

La raison pour laquelle j'utilise $(document).scrollTop au lieu de ie. $('html,body') est la cause, Chrome renvoie toujours 0 pour une raison quelconque. 

5
Steven

J'ai eu un même problème avec le défilement en chrome. Donc, je ai supprimé ces lignes de codes de mon fichier de style.

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

Maintenant, je peux jouer avec scroll et ça marche: 

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

Faites défiler le corps et vérifiez si cela a fonctionné:

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

Ceci est plus efficace que $("html, body").animate car une seule animation est utilisée, pas deux. Ainsi, un seul rappel est déclenché, pas deux.

2
NVI

peut-être que vous voulez dire top: 0

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

depuis animate docs

.animate (properties, [durée], [assouplissement], [rappel])
properties Une carte des propriétés CSS vers lesquelles l'animation se déplacera.
...

ou $(window).scrollTop()?

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

J'utilise:

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

parce que read scrolltop jQuery ne fonctionne pas dans Chrome mais fonctionne dans Firefox

1
Aamir Afridi
// 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");

MAIS, la meilleure approche consiste à faire défiler un identifiant dans votre fenêtre d’affichage en utilisant uniquement l’API native (puisque vous faites défiler vers le haut de toute façon, cela peut être uniquement votre div externe):

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

Si tout fonctionne bien pour Mozilla, avec html, sélecteur de corps, le problème est probablement lié au débordement. Si le débordement dans html ou body est défini sur auto, cela empêchera chrome de fonctionner correctement , car quand il est réglé sur auto, la propriété scrollTop sur animate ne fonctionnera pas, je ne sais pas exactement pourquoi! mais la solution est d’omettre le débordement, ne le réglez pas! cela l'a résolu pour moi! si vous le configurez automatiquement, enlevez-le! 

si vous le définissez sur masqué, procédez comme indiqué dans la réponse "utilisateur 2971963" (ctrl + f pour le trouver). espérons que cela est utile!

0
Mohamed Allal

Donc, j'avais ce problème aussi et j'ai écrit cette fonction:

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

J'espère que ce sera utile pour les autres programmeurs.

0
Vladimir A.

Une meilleure façon de résoudre ce problème consiste à utiliser une fonction comme celle-ci:

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

Ceci fonctionnera sur tous les navigateurs et empêchera FireFox de faire défiler deux fois (ce qui se produit si vous utilisez la réponse acceptée - $("html,body").animate({ scrollTop: 0 }, "slow");).

0
Chuck Le Butt

En testant sur Chrome, Firefox et Edge, la seule solution qui a bien fonctionné pour moi utilise setTimeout avec la solution d'Aaron de la manière suivante:

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

Aucune des autres solutions n'a réinitialisé le scrollTop précédent, lorsque j'ai rechargé la page, dans Chrome et Edge pour moi . Malheureusement, il y a encore un petit "coup sec" dans Edge.

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

Ce conflit CSS avec scroll to top so so so this 

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