Làm cách nào để cuộn lên đầu trang với JavaScript / jQuery?


159

Có cách nào để kiểm soát cuộn trình duyệt bằng JavaScript / jQuery không?

Khi tôi cuộn trang của mình xuống một nửa, sau đó kích hoạt tải lại, tôi muốn trang đi lên trên cùng, nhưng thay vào đó, nó cố gắng tìm vị trí cuộn cuối cùng. Vì vậy, tôi đã làm điều này:

$('document').ready(function() {
   $(window).scrollTop(0);
});

Nhưng không có may mắn.

BIÊN TẬP :

Vì vậy, cả hai câu trả lời của bạn đều hoạt động khi tôi gọi chúng sau khi tải trang - Cảm ơn. Tuy nhiên, nếu tôi chỉ làm mới trên trang, có vẻ như trình duyệt sẽ tính toán và cuộn đến vị trí cuộn cũ của nó SAU.ready sự kiện (tôi cũng đã thử chức năng body onload ()).

Vì vậy, theo dõi là, có cách nào để TRƯỚC trình duyệt cuộn đến vị trí trong quá khứ của nó, hoặc cuộn lại lên đầu SAU KHI nó làm việc của nó?


1
Điều gì xảy ra khi bạn làm điều đó từ $ (window) .load ()?
mpdon Arena

2
@ MPD- Ý tưởng tuyệt vời! ... nhưng chỉ cần thử nó và điều chỉnh cuộn vẫn xảy ra sau đó. Tuy nhiên, cảm ơn vì tiền boa, nó thực sự giúp ích cho câu hỏi khác của tôi: stackoverflow.com/questions/4210829/ . Nếu bạn muốn trả lời rằng tôi sẽ cung cấp cho bạn một số up.
Yarin

@Yarin Xin lỗi bạn đã phải chờ 9 năm cho việc này. Bạn cần đặt history.scrollRestoration trước khi bạn cố gắng cuộn. Xem câu trả lời của tôi.
RayLovless

Câu trả lời:


16

Wow, tôi trễ 9 năm cho câu hỏi này. Ở đây bạn đi:

Thêm mã này vào tải của bạn.

// This prevents the page from scrolling down to where it was previously.
if ('scrollRestoration' in history) {
    history.scrollRestoration = 'manual';
}
// This is needed if the user scrolls down during page load and you want to make sure the page is scrolled to the top once it's fully loaded. This has Cross-browser support.
window.scrollTo(0,0);

history.scrollRestoration Trình duyệt hỗ trợ:

Chrome: được hỗ trợ (từ 46)

Firefox: được hỗ trợ (từ 46)

IE / Edge: không được hỗ trợ (Chưa ..)

Opera: được hỗ trợ (từ 33)

Safari: được hỗ trợ

Đối với IE / Edge nếu bạn muốn cuộn lại lên đầu SAU KHI nó tự động ghi xuống thì điều này làm việc với tôi:

var isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
var isEdge = /Edge/.test(navigator.userAgent);
if(isIE11 || isEdge) {
    setTimeout(function(){ window.scrollTo(0, 0); }, 300);  // adjust time according to your page. The better solution would be to possibly tie into some event and trigger once the autoscrolling goes to the top.
} 

Cảm ơn @RayLovless - thật không may, điều này không được trình duyệt MS hỗ trợ (vì dĩ nhiên). Xem caniuse.com/#feat=mdn-api_history_scrollrestorationdeveloper.mozilla.org/de/docs/Web/API/
trộm

@Yarin, Điểm tốt. Tôi đã cập nhật bài viết của mình. Điều đó có trả lời câu hỏi của bạn không?
RayLovless

312

Trình duyệt chéo, giải pháp JavaScript thuần túy:

document.body.scrollTop = document.documentElement.scrollTop = 0;

3
Vì bạn đang sử dụng jQuery, bạn có thể thử điều này:$(window).one("scroll",function() { /* the code from my answer here */ });
Niet the Dark Absol

Để làm việc này trên các trình duyệt chéo IE / Chrome / FF của tôi, tôi phải kết hợp câu trả lời Niet Dark Absol và câu trả lời user113716 (sử dụng thời gian chờ).
Panini trưa

Không hoạt động trên CentOS 6.7 bằng FF 45.1.0. Tôi gói nó trong một tài liệu. Đã sẵn sàng để chắc chắn.
Brandon Elliott

Chỉ muốn chỉ ra rằng từ thử nghiệm của tôi (trên các phiên bản chrome / 2018 hiện đại) mà giải pháp này hoạt động đáng tin cậy hơn
mattLummus

Điều này không "TRƯỚC trình duyệt cuộn đến vị trí trong quá khứ". Xem câu trả lời của tôi.
RayLovless

85

Bạn gần như đã có nó - bạn cần phải scrollTopbật body, không phải window:

$(function() {
   $('body').scrollTop(0);
});

BIÊN TẬP:

Có lẽ bạn có thể thêm một neo trống vào đầu trang:

$(function() {
   $('<a name="top"/>').insertBefore($('body').children().eq(0));
   window.location.hash = 'top';
});

3
Đã thử điều này ngày hôm nay và không hoạt động trong FF16. Sử dụng JS thuần túy, được xem thấp hơn trên trang này, thay vào đó: document.body.scrollTop = document.documentEuity.scrollTop = 0;
Gigi2m02

2
Đoạn mã trên sẽ hoạt động chính xác trong các trình duyệt Hiện đại như FF, Chrome nhưng nó sẽ không hoạt động trong IE8 và bên dưới cố gắng thêm cả hai 'html','body'vì các trình duyệt hiện đại sẽ cuộn dựa trên cơ thể nhưng IE8 trở xuống sẽ chỉ cuộn với 'html', 'body'
Rajesh

17

Có cách nào để ngăn chặn trình duyệt cuộn đến vị trí trong quá khứ của nó, hoặc cuộn lại lên đầu SAU KHI làm việc đó không?

Các giải pháp jquery sau đây làm việc cho tôi:

$(window).unload(function() {
    $('body').scrollTop(0);
});

phải cuộn lên trên cùng trước khi làm mới
Morgan T.

Không hoàn toàn chéo trình duyệt, nhưng vẫn hoạt động cho hầu hết. Khi kết hợp với một số câu trả lời khác, đây là một bổ sung tốt
Brad Decker

16

Đây là phiên bản cuộn hoạt hình JavaScript thuần túy dành cho người không có jQuery: D

var stepTime = 20;
var docBody = document.body;
var focElem = document.documentElement;

var scrollAnimationStep = function (initPos, stepAmount) {
    var newPos = initPos - stepAmount > 0 ? initPos - stepAmount : 0;

    docBody.scrollTop = focElem.scrollTop = newPos;

    newPos && setTimeout(function () {
        scrollAnimationStep(newPos, stepAmount);
    }, stepTime);
}

var scrollTopAnimated = function (speed) {
    var topOffset = docBody.scrollTop || focElem.scrollTop;
    var stepAmount = topOffset;

    speed && (stepAmount = (topOffset * stepTime)/speed);

    scrollAnimationStep(topOffset, stepAmount);
};

Và sau đó:

<button onclick="scrollTopAnimated(1000)">Scroll Top</button>

1
Mát mẻ. Mặc dù, tôi thích requestAnimationStepthay vì setTimeout. Ngoài ra, nó không trả lời câu hỏi của OP.
Quentin Roy

thực hiện điều này trong Angular. hoạt động như một lá bùa. Cảm ơn
Ahmad

12

CẬP NHẬT

Chuyển đến đầu trang với hiệu ứng cuộn dễ dàng hơn một chút trong javascript bây giờ với:

https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll

window.scroll({
 top: 0, 
 left: 0, 
 behavior: 'smooth' 
});

THẬN TRỌNG

Chúng tôi đã sử dụng điều này trong các dự án gần đây của chúng tôi, nhưng tôi vừa kiểm tra tài liệu mozilla ngay bây giờ trong khi cập nhật câu trả lời của tôi và tôi tin rằng nó đã được cập nhật. Ngay bây giờ phương pháp này là window.scroll(x-coord, y-coord)và không đề cập đến hoặc hiển thị ví dụ sử dụng các objecttham số mà bạn có thể thiết lập behaviorđể smooth. Tôi vừa thử mã và nó vẫn hoạt động trong chrome và firefox và tham số đối tượng vẫn còn trong spec .

Vì vậy, sử dụng cẩn thận hoặc bạn có thể sử dụng Polyfill này . Bên cạnh di chuyển lên trên, polyfill này cũng xử lý các phương pháp khác: window.scrollBy, element.scrollIntoViewvv


TRẢ LỜI

Đây là javascriptthực hiện vanilla của chúng tôi . Nó có tác dụng nới lỏng đơn giản để người dùng không bị sốc sau khi nhấp vào nút Lên trên .

Nó rất nhỏ và thậm chí còn nhỏ hơn khi thu nhỏ. Các nhà phát triển đang tìm kiếm một phương pháp thay thế cho phương pháp jquery nhưng muốn có kết quả tương tự có thể thử điều này.

Mã não

document.querySelector("#to-top").addEventListener("click", function(){

    var toTopInterval = setInterval(function(){

        var supportedScrollTop = document.body.scrollTop > 0 ? document.body : document.documentElement;

        if (supportedScrollTop.scrollTop > 0) {
            supportedScrollTop.scrollTop = supportedScrollTop.scrollTop - 50;
        }

        if (supportedScrollTop.scrollTop < 1) {
            clearInterval(toTopInterval);
        }

    }, 10);

},false);

HTML

<button id="to-top">To Top</button>

Chúc mừng!


8

Điều này làm việc cho tôi:

window.onload = function() {
    // short timeout
    setTimeout(function() {
        $(document.body).scrollTop(0);
    }, 15);
};

Sử dụng một đoạn ngắn setTimeoutbên trong onloadđể cung cấp cho trình duyệt một cơ hội để thực hiện cuộn.


Để làm việc này trên các trình duyệt chéo IE / Chrome / FF của tôi, tôi phải kết hợp câu trả lời Niet Dark Absol và câu trả lời user113716 (sử dụng thời gian chờ).
Panini trưa

@Panini: đề xuất của bạn hoạt động với tôi trên Chrome / FF, nhưng không phải IE11.
EML

8

Bạn có thể sử dụng với jQuery

jQuery(window).load(function(){

    jQuery("html,body").animate({scrollTop: 100}, 1000);

});

Về cơ bản, đây là những gì tôi HOÀN TOÀN tìm thấy để hoạt động trên CentOS 6.7 bằng FF 45.1.0. Phiên bản hơi khác của tôi (được bao bọc trong chức năng tải cửa sổ) là: $ ("html, body"). Animate ({scrollTop: 0}, 1);
Brandon Elliott

6

Sử dụng chức năng sau

window.scrollTo(xpos, ypos)

Ở đây xpose là bắt buộc. Tọa độ để cuộn đến, dọc theo trục x (ngang), tính bằng pixel

ypose cũng được yêu cầu. Tọa độ để cuộn đến, dọc theo trục y (dọc), tính bằng pixel


5
$(function() {
    // the element inside of which we want to scroll
        var $elem = $('#content');

        // show the buttons
    $('#nav_up').fadeIn('slow');
    $('#nav_down').fadeIn('slow');  

        // whenever we scroll fade out both buttons
    $(window).bind('scrollstart', function(){
        $('#nav_up,#nav_down').stop().animate({'opacity':'0.2'});
    });
        // ... and whenever we stop scrolling fade in both buttons
    $(window).bind('scrollstop', function(){
        $('#nav_up,#nav_down').stop().animate({'opacity':'1'});
    });

        // clicking the "down" button will make the page scroll to the $elem's height
    $('#nav_down').click(
        function (e) {
            $('html, body').animate({scrollTop: $elem.height()}, 800);
        }
    );
        // clicking the "up" button will make the page scroll to the top of the page
    $('#nav_up').click(
        function (e) {
            $('html, body').animate({scrollTop: '0px'}, 800);
        }
    );
 });

Dùng cái này


Đẹp! Hoạt động tốt với hình ảnh động!
Sakth Xoay

4

Đoạn mã sau hoạt động trong Firefox, Chrome và Safari , nhưng tôi không thể kiểm tra điều này trong Internet Explorer. Ai đó có thể kiểm tra nó, và sau đó chỉnh sửa câu trả lời hoặc nhận xét của tôi về nó?

$(document).scrollTop(0);

4

Giải pháp Javascript thuần túy (hoạt hình) của tôi:

function gototop() {
    if (window.scrollY>0) {
        window.scrollTo(0,window.scrollY-20)
        setTimeout("gototop()",10)
    }
}

Giải trình:

window.scrollY là một biến được duy trì bởi trình duyệt về số lượng pixel từ đầu mà cửa sổ đã được cuộn qua.

window.scrollTo(x,y) là một hàm cuộn cửa sổ một lượng pixel cụ thể trên trục x và trên trục y.

Do đó, window.scrollTo(0,window.scrollY-20)di chuyển trang 20 pixel về phía trên.

Hàm setTimeoutgọi lại hàm sau 10 mili giây để sau đó chúng ta có thể di chuyển nó thêm 20 pixel (hoạt hình) và ifcâu lệnh sẽ kiểm tra nếu chúng ta vẫn cần cuộn.


3

Tại sao bạn không sử dụng một số yếu tố tham chiếu ngay từ đầu tệp html của mình, như

<div id="top"></div>

và sau đó, khi tải trang, chỉ cần làm

$(document).ready(function(){

    top.location.href = '#top';

});

Nếu trình duyệt cuộn sau khi chức năng này kích hoạt, bạn chỉ cần làm

$(window).load(function(){

    top.location.href = '#top';

});

3
cái này hiệu quả với tôi, nhưng nó thêm #top trong url, bạn có thể vui lòng cho tôi biết làm thế nào tôi có thể tránh điều này không, nhưng đồng thời, không ảnh hưởng đến chức năng
Abbas

3

Cuộn trình duyệt chéo lên trên cùng:

        if($('body').scrollTop()>0){
            $('body').scrollTop(0);         //Chrome,Safari
        }else{
            if($('html').scrollTop()>0){    //IE, FF
                $('html').scrollTop(0);
            }
        } 

Cuộn trình duyệt chéo đến một phần tử có id = div_id:

        if($('body').scrollTop()>$('#div_id').offset().top){
            $('body').scrollTop($('#div_id').offset().top);         //Chrome,Safari
        }else{
            if($('html').scrollTop()>$('#div_id').offset().top){    //IE, FF
                $('html').scrollTop($('#div_id').offset().top);
            }
        } 

2

Để trả lời câu hỏi đã chỉnh sửa của bạn, bạn có thể đăng ký onscrolltrình xử lý như vậy:

document.documentElement.onscroll = document.body.onscroll = function() {
    this.scrollTop = 0;
    this.onscroll = null;
}

Điều này sẽ làm cho nó để lần thử đầu tiên khi cuộn (có khả năng là thao tác tự động được thực hiện bởi trình duyệt) sẽ bị hủy hiệu quả.


Giải pháp tuyệt vời - Tôi sẽ dùng thử
Yarin

2

Nếu bạn đang ở chế độ quircks (cảm ơn @Niet the Dark Absol):

document.body.scrollTop = document.documentElement.scrollTop = 0;

Nếu bạn đang ở chế độ nghiêm ngặt:

document.documentElement.scrollTop = 0;

Không cần jQuery ở đây.


2

Đây là hoạt động:

jQuery(document).ready(function() {
     jQuery("html").animate({ scrollTop: 0 }, "fast");
});

2

Trong trường hợp của tôi, cơ thể không hoạt động:

$('body').scrollTop(0);

Nhưng HTML đã hoạt động:

$('html').scrollTop(0);

1
Thêm cả hai 'html','body'như các trình duyệt hiện đại FF, Chrome sẽ cuộn dựa trên cơ thể nhưng IE8 trở xuống sẽ chỉ cuộn với'html','body'
Rajesh

2

Sự kết hợp của hai điều này đã giúp tôi. Không có câu trả lời nào khác giúp tôi vì tôi có một sidenav không được cuộn.

 setTimeout(function () {
        window.scroll({
                        top: 0,
                        left: 0,
                        behavior: 'smooth'
                    });

    document.body.scrollTop = document.documentElement.scrollTop = 0;

}, 15);

1
var totop = $('#totop');
totop.click(function(){
 $('html, body').stop(true,true).animate({scrollTop:0}, 1000);
 return false;
});

$(window).scroll(function(){
 if ($(this).scrollTop() > 100){ 
  totop.fadeIn();
 }else{
  totop.fadeOut();
 }
});

<img id="totop" src="img/arrow_up.png" title="Click to go Up" style="display:none;position:fixed;bottom:10px;right:10px;cursor:pointer;cursor:hand;"/>


1

Nếu bất cứ ai đang sử dụng thiết kế góc cạnh và vật liệu với sidenav. Điều này sẽ đưa bạn đến đầu trang:

let ele = document.getElementsByClassName('md-sidenav-content');
    let eleArray = <Element[]>Array.prototype.slice.call(ele);
    eleArray.map( val => {
        val.scrollTop = document.documentElement.scrollTop = 0;
    });

0

Seeint băm nên làm công việc. Nếu bạn có một tiêu đề, bạn có thể sử dụng

window.location.href = "#headerid";

nếu không, một mình # sẽ hoạt động

window.location.href = "#";

Và khi nó được ghi vào url, nó sẽ ở lại nếu bạn làm mới.

Trên thực tế, bạn không cần sự kiện JavaScript vì nếu bạn muốn làm điều đó trong một sự kiện onclick, bạn chỉ nên đặt một liên kết bắt nguồn từ phần tử của bạn và cung cấp cho nó # as href.


Btw, window.location không phải là một phần của cây nên hiện đang sử dụng để chờ tải.
xavierm02

0

Đầu tiên, thêm thẻ neo trống vào nơi bạn muốn đến

<a href="#topAnchor"></a> 

Bây giờ thêm một chức năng trong phần tiêu đề

 function GoToTop() {
            var urllocation = location.href;
            if (urllocation.indexOf("#topAnchor") > -1) {
                window.location.hash = "topAnchor";
            } else {
                return false;
            }
        }

cuối cùng thêm một sự kiện onload vào thẻ body

<body onload="GoToTop()">

0

Một phiên bản chung hoạt động cho bất kỳ giá trị X và Y nào, và giống như window.scrollTo api, chỉ với việc thêm scrollDuration.

* Phiên bản chung khớp với window.scrollTo trình duyệt api **

function smoothScrollTo(x, y, scrollDuration) {
    x = Math.abs(x || 0);
    y = Math.abs(y || 0);
    scrollDuration = scrollDuration || 1500;

    var currentScrollY = window.scrollY,
        currentScrollX = window.scrollX,
        dirY = y > currentScrollY ? 1 : -1,
        dirX = x > currentScrollX ? 1 : -1,
        tick = 16.6667, // 1000 / 60
        scrollStep = Math.PI / ( scrollDuration / tick ),
        cosParameterY = currentScrollY / 2,
        cosParameterX = currentScrollX / 2,
        scrollCount = 0,
        scrollMargin;

    function step() {        
        scrollCount = scrollCount + 1;  

        if ( window.scrollX !== x ) {
            scrollMargin = cosParameterX + dirX * cosParameterX * Math.cos( scrollCount * scrollStep );
            window.scrollTo( 0, ( currentScrollX - scrollMargin ) );
        } 

        if ( window.scrollY !== y ) {
            scrollMargin = cosParameterY + dirY * cosParameterY * Math.cos( scrollCount * scrollStep );
            window.scrollTo( 0, ( currentScrollY - scrollMargin ) );
        } 

        if (window.scrollX !== x || window.scrollY !== y) {
            requestAnimationFrame(step);
        }
    }

    step();
}

0

Tôi nhớ đã thấy điều này được đăng ở một nơi khác (tôi không thể tìm thấy ở đâu), nhưng điều này thực sự hoạt động tốt:

setTimeout(() => {
    window.scrollTo(0, 0);
}, 0);

Thật kỳ lạ, nhưng cách nó hoạt động dựa trên cách hoạt động của hàng đợi ngăn xếp của JavaScript. Giải thích đầy đủ được tìm thấy ở đây trong phần Zero Delays.

Ý tưởng cơ bản là thời gian setTimeoutkhông thực sự chỉ định lượng thời gian đã đặt mà nó sẽ chờ, nhưng lượng thời gian tối thiểu sẽ chờ. Vì vậy, khi bạn bảo nó đợi 0ms, trình duyệt sẽ chạy tất cả các quy trình được xếp hàng khác (như cuộn cửa sổ đến nơi bạn ở cuối cùng) và sau đó thực hiện cuộc gọi lại.


-1
 <script>
  sessionStorage.scrollDirection = 1;//create a session variable 
  var pageScroll = function() {
  window.scrollBy ({
   top: sessionStorage.scrollDirection,
   left: 0,
   behavior: 'smooth'
   });
   if($(window).scrollTop() + $(window).height() > $(document).height() - 1)
  {    
    sessionStorage.scrollDirection= Number(sessionStorage.scrollDirection )-300;
    setTimeout(pageScroll,50);//
   }
   else{
   sessionStorage.scrollDirection=Number(sessionStorage.scrollDirection )+1
   setTimeout(pageScroll,300); 
  }
};
pageScroll();
</script>

1
Chào mừng đến với stackoverflow. Ngoài mã bạn đã cung cấp, hãy thử đưa ra một số giải thích về lý do và cách khắc phục sự cố này.
jtate
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.