jQuery scrollTop не працює в Chrome, але працює у Firefox


80

Я використовував scrollTopфункцію в jQuery для навігації до початку, але дивно, що "плавна анімована прокрутка" перестала працювати в Safari та Chrome (прокрутка без плавної анімації) після внесення деяких змін.

Але це все ще працює безперебійно у Firefox. Що може бути не так?

Ось функція jQuery, яку я використовував,

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 чудово працює на chrome
jAndy

@jAndy, мені було цікаво, чому scrollTop, що не є дійсним властивістю css, працює на вашому демо? ... Ви можете поділитися деякою інформацією або посиланням про це?
Рейгель

@Reigel: Я повинен визнати, що не можу. Я використовую його майже як чорний ящик, але jQuery infact нормалізує його крос-браузер.
jAndy

@jAndy - гаразд ... але, мабуть, не доцільно використовувати scrollTopвсередині властивостей анімації css map ... Хоча я все-таки
копаю

Відповіді:


106

Спробуйте використовувати $("html,body").animate({ scrollTop: 0 }, "slow");

Це працює у мене в хромі.


Так, дякую. Просто та економія часу.
Maju

3
Це має побічний ефект: функцію зворотного виклику буде викликано двічі (по одному для кожного елемента). Будь-який розумний спосіб вирішити це, хто-небудь?
bububaba

8
Покладіть: if (this.nodeName == "BODY") {return; } на початку функції зворотного виклику, тому буде пройдений лише зворотний виклик з елемента html. Також пам’ятайте, що атрибут nodeName в елементах html завжди має великі регістри.
Боббі

1
Дякую @Bobby за те, що вказав на це! Надзвичайно корисно при використанні функції зворотного виклику, яку слід запускати один раз і працювати у всіх браузерах! ТА!
Себастьян

1
Мені довелося використовувати $ ("body, html") для роботи у всіх браузерах.
Том Кінкейд,

57

Якщо ваш htmlелемент CSS має таку overflowрозмітку, scrollTopвін не працюватиме.

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

Щоб дозволити scrollTopпрокрутку, змініть розмітку, видаліть overflowрозмітку з htmlелемента та додайте до bodyелемента.

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

4
йому, можливо, більше 4 років, але це все ще було вирішенням моєї проблеми
Рафаель Ротелок

1
@Leandro це рішення в chrome 41. не відбивайте відповіді, яка відповідає на питання.
worc

1
@Leandro Цей хлопець щойно врятував мені життя! це спрацювало для мене
liltof

о боже, це вирішило ДВІ проблеми для мене. Багато великих подяк <3
Osamah Aldoaiss

Я ... витратив понад 5 годин, намагаючись зрозуміти, чому це не працює. Щиро дякую за це!
PepperAddict

15

Це працює в обох браузерах, якщо ви використовуєте scrollTop () з 'document':

$(document).scrollTop();

... замість "html" або "body". В іншому випадку це не буде працювати одночасно в обох браузерах.


документ працював у мене, коли 'html' та 'body' не працювали. Дякую :)
ConorLuddy

5

Я успішно використовував це в Chrome, Firefox та Safari. Ще не зміг перевірити це в IE.

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

Причиною заяви "якщо" є перевірка, чи готовий користувач у верхній частині сайту. Якщо так, не робіть анімацію. Таким чином, нам не доведеться так турбуватися про роздільну здатність екрана.

Причину, яку я використовую $(document).scrollTopзамість ie. $('html,body')тому, що Chrome з якихось причин завжди повертає 0.


3

У мене була та ж проблема зі прокруткою хрому. Тому я видалив ці рядки кодів зі свого файлу стилів.

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

Тепер я можу грати зі прокруткою, і це працює:

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

Ого. Це повністю виправило мою проблему! Я взагалі не міг отримати scrollTop для роботи, але як тільки я видалив height: 100% з елемента body і html, він працював чудово. Дякую, дякую, дякую.
agon024

@ agon024, я теж щасливий;). Дійсно, я заснував це рішення після декількох годин тестування і спробував написати тут для когось, як ти.
RAM

2

Прокрутіть тіло та перевірте, чи воно працювало:

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

Це ефективніше, ніж $("html, body").animateтому, що використовується лише одна анімація, а не дві. Таким чином, спрацьовує лише один зворотний дзвінок, а не два.


Хороша робота! Мені дуже допомогло!
гогачинчаладзе

1

можливо, ти маєш на увазі top: 0

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

з анімованих документів

.animate ( властивості , [тривалість], [послаблення], [зворотний виклик])
властивості Карта властивостей CSS, до яких рухатиметься анімація.
...

чи $(window).scrollTop()?

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

як і раніше анімація не працює. Знайдено просте рішення. Мені довелося використовувати "body, html" або "html, body" замість просто "html".
Маджу

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

АЛЕ, найкращий підхід - прокрутити ідентифікатор у вікно перегляду, використовуючи лише власний api (оскільки ви все одно прокручуєте до верху, це може бути лише ваш зовнішній div):

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

Цей найкращий підхід оминає проблему з overflow-x: hidden;on htmlin chrome. Однак він не згладжує прокрутку, як .animate()це робить.
Джиммі


0

Кращий спосіб вирішити цю проблему - використовувати таку функцію:

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

Це буде працювати у всіх браузерах і запобігає прокрутці FireFox двічі (що відбувається, якщо ви використовуєте прийняту відповідь - $("html,body").animate({ scrollTop: 0 }, "slow");).


0

Тестування на Chrome, Firefox та Edge, єдиним рішенням, яке добре спрацювало для мене, є використання setTimeout із рішенням Aaron таким чином:

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

Жодне з інших рішень не скинуло попередню scrollTop, коли я перезавантажив сторінку, у Chrome та Edge для мене. На жаль, у Edge все ще є невеликий "штрих".


0

Отже, у мене теж була ця проблема, і я написав цю функцію:

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

Сподіваюся, це буде корисно для інших програмістів.


0

Якщо це добре працює для Mozilla, з html, селектором тіла, тоді є велика ймовірність, що проблема пов’язана з переповненням, якщо переповнення в html або body встановлено на auto, то це призведе до того, що chrome буде працювати неправильно , тому що, коли для нього встановлено значення auto, властивість scrollTop на animate не буде працювати, я не знаю точно чому! але рішення полягає в тому, щоб опустити переповнення, не встановлюйте його! це вирішило це для мене! якщо ви встановлюєте його для автоматичного, зніміть його!

якщо ви встановлюєте його як прихований, виконайте те, що описано у відповіді "user2971963" (ctrl + f, щоб знайти його). сподіваюся, це корисно!


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

Цей CSS конфліктує з прокруткою до початку, тому подбайте про це

 html, body {
         overflow-x: hidden;        
    }

-3

Я не думаю, що scrollTop є допустимою властивістю. Якщо ви хочете анімувати прокрутку, спробуйте плагін scrollTo для jquery

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


Коли я сказав, що scrollTop () є властивістю? Вам не потрібно використовувати плагін, оскільки ця функція вже реалізована в jQuery.
Bayard Randel

@Bayan - на вашу видалену відповідь буде відповідь, When did I say scrollTop() is a property?і крім того, ОР хоче плавну анімацію, може scrollTop()робити плавно? ... і варто зазначити, що у відповіді Бена вище чітко зазначено, I don't think the scrollTop is a valid propertyі ви прокоментували як scrollTop() is valid jQuery...
Рейгель

1
@Maju досить справедливо. Радий бачити, що у вас проблему відсортували :)
Бен Роу,

@Reigel ScrollTopчудово розгладжує
Чак Ле Батт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.