jQuery scrollTop không hoạt động trong Chrome nhưng hoạt động trong Firefox


80

Tôi đã sử dụng một scrollTopchức năng trong jQuery để điều hướng lên trên cùng, nhưng kỳ lạ là 'cuộn động mượt mà' đã ngừng hoạt động trong Safari và Chrome (cuộn mà không có hoạt ảnh mượt) sau khi tôi thực hiện một số thay đổi.

Nhưng nó vẫn hoạt động trơn tru trên Firefox. điều gì sai?

Đây là hàm jQuery tôi đã sử dụng,

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 hoạt động tốt trên chrome
jAndy

@jAndy, tôi đã tự hỏi tại sao scrollTop, không phải là thuộc tính css hợp lệ, hoạt động trên bản demo của bạn? ... bạn có thể chia sẻ một số thông tin hoặc liên kết về nó không?
Reigel

@Reigel: Tôi phải thừa nhận, tôi không thể. Tôi sử dụng nó giống như một hộp đen, nhưng jQuery infact sẽ bình thường hóa nó qua trình duyệt.
jAndy

@jAndy - okay ... nhưng tôi đoán nó sẽ không được khuyến khích sử dụng scrollTopbên trong Animate thuộc tính bản đồ css ... Tôi vẫn đào mặc dù ..
Reigel

Câu trả lời:


106

Hãy thử sử dụng $("html,body").animate({ scrollTop: 0 }, "slow");

Điều này làm việc cho tôi trong chrome.


Vâng, cảm ơn. Đơn giản và tiết kiệm thời gian.
Maju

3
Điều này có một tác dụng phụ: một hàm gọi lại sẽ được gọi hai lần (một lần cho mỗi phần tử). Có giải pháp thông minh nào cho việc này không, có ai không?
bububaba

8
Đặt: if (this.nodeName == "BODY") {return; } ở đầu hàm gọi lại của bạn, do đó chỉ có lệnh gọi lại từ phần tử html mới được thực hiện. Ngoài ra, hãy nhớ rằng thuộc tính nodeName trên các phần tử html luôn là chữ hoa.
Bobby

1
Cảm ơn bạn @Bobby đã chỉ ra điều này! Cực kỳ hữu ích khi sử dụng chức năng gọi lại mà một chức năng sẽ kích hoạt một lần và hoạt động trên tất cả các trình duyệt! TA!
Sebastian

1
Tôi đã phải sử dụng $ ("body, html") để hoạt động trong tất cả các trình duyệt.
Tom Kincaid,

57

Nếu htmlphần tử CSS của bạn có overflowđánh dấu sau , scrollTopsẽ không hoạt động.

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

Để cho phép scrollTopcuộn, hãy sửa đổi đánh dấu của bạn, hãy xóa overflowđánh dấu khỏi htmlphần tử và nối vào một bodyphần tử.

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

4
nó có thể hơn 4 tuổi, nhưng nó vẫn là giải pháp cho vấn đề của tôi
Rafael Rotelok

1
@Leandro đây là giải pháp trong chrome 41. không làm nản lòng một câu trả lời trả lời câu hỏi.
worc

1
@Leandro Anh chàng này vừa cứu mạng tôi! nó làm việc cho tôi
liltof

trời ơi cái này giải quyết được HAI vấn đề cho tôi. Nhiều cảm ơn nhiều <3
Osamah Aldoaiss

Tôi ... đã dành hơn 5 giờ để cố gắng tìm ra lý do tại sao nó không hoạt động. Cám ơn bạn rất nhiều về điều này.
PepperAddict

15

Nó hoạt động trên cả hai trình duyệt nếu bạn sử dụng scrollTop () với 'tài liệu':

$(document).scrollTop();

... thay vì 'html' hoặc 'body'. Theo cách khác, nó sẽ không hoạt động cùng lúc trên cả hai trình duyệt.


tài liệu hoạt động cho tôi khi 'html' và 'body' không hoạt động. Cảm ơn :)
ConorLuddy

5

Tôi đã sử dụng điều này thành công trong Chrome, Firefox và Safari. Chưa thể kiểm tra nó trong IE.

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

Lý do cho câu lệnh "if" là để kiểm tra xem tất cả người dùng đã sẵn sàng ở đầu trang web chưa. Nếu vậy, đừng làm hoạt ảnh. Bằng cách đó, chúng tôi không phải lo lắng quá nhiều về độ phân giải màn hình.

Lý do tôi sử dụng $(document).scrollTopthay vì tức là. $('html,body')là nguyên nhân khiến Chrome luôn trả về 0 vì một số lý do.


2

Cuộn phần thân và kiểm tra xem nó có hoạt động không:

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

Điều này hiệu quả hơn $("html, body").animatevì chỉ sử dụng một hoạt ảnh chứ không phải hai. Do đó, chỉ có một lệnh gọi lại kích hoạt, không phải hai.


Công việc tốt! Đã giúp tôi rất nhiều!
gogachinchaladze 17/10/17

2

Tôi đã gặp vấn đề tương tự với việc cuộn trong chrome. Vì vậy, tôi đã xóa các dòng mã này khỏi tệp kiểu của mình.

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

Bây giờ tôi có thể chơi với cuộn và nó hoạt động:

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

Chà. Điều này hoàn toàn khắc phục sự cố của tôi! Tôi không thể làm cho scrollTop hoạt động nhưng một khi tôi đã xóa chiều cao: 100% khỏi phần thân và phần tử html thì nó hoạt động tốt. Cảm ơn bạn, cảm ơn bạn, cảm ơn bạn.
agon024

@ agon024, mình cũng vui lắm;). Thực sự tôi đã thành lập giải pháp này sau vài giờ thử nghiệm và thử và viết ở đây cho một số người như bạn.
RAM

1

có thể ý bạn là top: 0

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

từ tài liệu hoạt hình

.animate ( thuộc tính , [thời gian], [giảm bớt], [callback])
tính Một bản đồ thuộc tính CSS mà các hình ảnh động sẽ tiến tới.
...

hoặc $(window).scrollTop()?

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

vẫn là hoạt ảnh không hoạt động. Tìm thấy giải pháp đơn giản, tôi phải sử dụng "body, html" hoặc "html, body" thay vì chỉ "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");

NHƯNG, cách tốt nhất là cuộn một id vào khung nhìn của bạn bằng cách chỉ sử dụng api gốc (vì dù sao thì bạn cũng cuộn lên trên cùng, đây có thể chỉ là div bên ngoài của bạn):

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

Cách tiếp cận tốt nhất này sẽ bỏ qua sự cố với overflow-x: hidden;bật htmltrong chrome. Tuy nhiên, nó không mượt mà cuộn như .animate()vậy.
Jimmy


0

Một cách tốt hơn để giải quyết vấn đề này là sử dụng một hàm như sau:

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

Điều này sẽ hoạt động trên tất cả các trình duyệt và ngăn FireFox cuộn lên hai lần (đó là điều sẽ xảy ra nếu bạn sử dụng câu trả lời được chấp nhận - $("html,body").animate({ scrollTop: 0 }, "slow");).


0

Thử nghiệm trên Chrome, Firefox và Edge, giải pháp duy nhất phù hợp với tôi là sử dụng setTimeout với giải pháp của Aaron theo cách này:

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

Không có giải pháp nào khác đã đặt lại scrollTop của previuos, khi tôi tải lại trang, trong Chrome và Edge cho tôi. Thật không may là vẫn còn một chút "nhấp nháy" trong Edge.


0

Vì vậy, tôi cũng gặp sự cố này và tôi đã viết hàm này:

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

Tôi hy vọng nó sẽ hữu ích cho các lập trình viên khác.


0

Nếu nó hoạt động tốt với Mozilla, với html, body selector, thì rất có thể sự cố liên quan đến tràn, nếu tràn trong html hoặc nội dung được đặt thành tự động, thì điều này sẽ khiến chrome hoạt động không tốt , vì khi nó được đặt thành tự động, thuộc tính scrollTop trên animate sẽ không hoạt động, tôi không biết chính xác tại sao! nhưng giải pháp là bỏ phần tràn, đừng đặt nó! điều đó đã giải quyết nó cho tôi! nếu bạn đang đặt nó thành tự động, hãy tắt nó đi!

nếu bạn đang đặt nó thành ẩn, thì hãy làm như nó được mô tả trong câu trả lời "user2971963" (ctrl + f để tìm nó). hy vọng điều này là hữu ích!


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

CSS này xung đột với cuộn lên đầu, vì vậy hãy chú ý đến điều này

 html, body {
         overflow-x: hidden;        
    }

-3

Tôi không nghĩ rằng scrollTop là một thuộc tính hợp lệ. Nếu bạn muốn tạo hiệu ứng cuộn, hãy thử plugin scrollTo cho jquery

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


Khi tôi nói scrollTop () là một thuộc tính? Bạn không cần sử dụng plugin vì chức năng này đã được triển khai trong jQuery.
Bayard Randel

@Bayan - câu trả lời đã xóa của bạn sẽ có câu trả lời When did I say scrollTop() is a property?và bên cạnh đó, OP muốn có một hình ảnh động trơn tru, có thể scrollTop()làm mịn ... và nó đáng chú ý là câu trả lời của Ben ở trên nêu rõ,? I don't think the scrollTop is a valid propertyVà bạn nhận xét như scrollTop() is valid jQuery...
Reigel

1
@Maju đủ công bằng. Vui mừng khi thấy bạn có vấn đề của bạn được sắp xếp tuy nhiên :)
Bến Rowe

@Reigel ScrollTophoạt động mượt mà: jsfiddle.net/JohnnyWalkerDesign/w4hetv45
Chuck Le Butt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.