Jak przewinąć na górę strony za pomocą JavaScript / jQuery?


159

Czy istnieje sposób kontrolowania przewijania przeglądarki za pomocą JavaScript / jQuery?

Kiedy przewijam stronę do połowy, a następnie uruchamiam ponowne ładowanie, chcę, aby strona wróciła do góry, ale zamiast tego próbuje znaleźć ostatnią pozycję przewijania. Więc zrobiłem to:

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

Ale bez szczęścia.

EDYCJA :

Więc obie odpowiedzi zadziałały, kiedy dzwonię do nich po załadowaniu strony - Dzięki. Jeśli jednak po prostu odświeżę stronę, wygląda na to, że przeglądarka oblicza i przewija do swojej starej pozycji przewijania PO .readyzdarzeniu (przetestowałem również funkcję body onload ()).

Zatem następująca kwestia brzmi: czy istnieje sposób, aby ZAPOBIEGŁA przewijaniu przeglądarki do jej poprzedniej pozycji, czy też aby ponownie przewinąć do góry, PO tym, jak to zrobi?


1
Co się dzieje, gdy robisz to z $ (window) .load ()?
mpdonadio

2
@ MPD- Doskonały pomysł! ... ale właśnie spróbowałem, a regulacja przewijania nadal ma miejsce. Jednak dzięki za wskazówkę, tak naprawdę pomaga w przypadku innego mojego pytania: stackoverflow.com/questions/4210829/… . Jeśli chcesz odpowiedzieć na to pytanie, dam ci kilka uwag.
Yarin

@Yarin Przepraszamy, że musiałeś na to czekać 9 lat. Musisz ustawić history.scrollRestoration przed próbą przewijania. Zobacz moją odpowiedź.
RayLoveless

Odpowiedzi:


16

Wow, spóźniłem się 9 lat na to pytanie. Proszę bardzo:

Dodaj ten kod do swojego pliku onload.

// 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 Browser - obsługa:

Chrome: obsługiwany (od 46)

Firefox: obsługiwany (od 46)

IE / Edge: nieobsługiwane (jeszcze ...)

Opera: obsługiwana (od 33)

Safari: obsługiwane

W przypadku IE / Edge, jeśli chcesz ponownie przewinąć do góry PO automatycznym przewijaniu w dół, to zadziałało dla mnie:

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.
} 

Dzięki @RayLoveless - niestety nie jest to obsługiwane przez przeglądarki MS (bo oczywiście). Zobacz caniuse.com/#feat=mdn-api_history_scrollrestoration and developer.mozilla.org/de/docs/Web/API/…
Yarin

@Yarin, słuszna uwaga. Zaktualizowałem swój post. Czy to jest odpowiedź na Twoje pytanie?
RayLoveless

312

Rozwiązanie oparte na czystym JavaScript dla różnych przeglądarek:

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

3
Ponieważ używasz jQuery, możesz spróbować tego:$(window).one("scroll",function() { /* the code from my answer here */ });
Niet the Dark Absol

Aby to zadziałało na moich przeglądarkach IE / Chrome / FF, muszę połączyć odpowiedź Niet Dark Absol i odpowiedź user113716 (używając limitu czasu).
Panini Luncher

Nie działał w CentOS 6.7 przy użyciu FF 45.1.0. Zapakowałem go w dokument. Gotowe dla pewności.
Brandon Elliott

Chcę tylko zaznaczyć, że z moich testów (na nowoczesnych / 2018 wersjach chromu w zestawie) to rozwiązanie działa bardziej niezawodnie
mattLummus

Nie oznacza to „ZAPOBIEGANIA przewijaniu przeglądarki do poprzedniej pozycji”. Zobacz moją odpowiedź.
RayLoveless

85

Jesteś prawie dostał go - trzeba ustawić scrollTopna bodynie window:

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

EDYTOWAĆ:

Może mógłbyś dodać pustą kotwicę na górze strony:

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

3
Wypróbowałem to dzisiaj i nie działało w FF16. Zamiast tego używam czystego JS, patrz niżej na tej stronie: document.body.scrollTop = document.documentElement.scrollTop = 0;
Gigi2m02

2
Powyższy kod będzie działał poprawnie w nowoczesnych przeglądarkach, takich jak FF, Chrome, ale nie będzie działał w IE8, a poniżej spróbuj dodać oba, 'html','body'ponieważ nowoczesne przeglądarki będą przewijać na podstawie treści, ale IE8 i poniżej będą przewijać się tylko za pomocą „html”, „body”
Rajesh

17

Czy istnieje sposób ZAPOBIEGANIA przewijaniu przeglądarki do jej poprzedniej pozycji, czy też ponowne przewinięcie do góry PO tym, jak coś zrobi?

U mnie działa następujące rozwiązanie jQuery:

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

tak, przewiń do góry przed odświeżeniem
Morgan T.

Niezupełnie między przeglądarkami, ale nadal działa dla większości. W połączeniu z niektórymi innymi odpowiedziami jest to dobry dodatek
Brad Decker

16

Oto czysta animowana wersja przewijania JavaScript dla no-jQuery'ers: 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);
};

I wtedy:

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

1
Chłodny. Chociaż wolałbym requestAnimationStepzamiast setTimeout. Nie odpowiada również na pytanie OP.
Quentin Roy,

zaimplementował to w Angular. działa jak marzenie. Dzięki
Ahmad

12

AKTUALIZACJA

Przechodzenie na górę strony z efektem przewijania jest teraz nieco łatwiejsze w javascript dzięki:

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

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

UWAGA

Używaliśmy tego w naszych nowszych projektach, ale właśnie sprawdziłem dokument Mozilli podczas aktualizacji mojej odpowiedzi i uważam, że został zaktualizowany. W tej chwili metoda jest window.scroll(x-coord, y-coord)i nie wspomina ani nie pokazuje przykładów, które używają objectparametru, w którym można ustawić behaviorto smooth. Właśnie wypróbowałem kod i nadal działa w Chrome i Firefox, a parametr obiektu jest nadal w specyfikacji .

Więc używaj tego ostrożnie lub możesz użyć tego Polyfill . Oprócz przewijania do góry, to polyfill obsługuje także inne metody: window.scrollBy, element.scrollIntoView, itd.


STARA ODPOWIEDŹ

To jest nasza javascriptimplementacja waniliowa . Ma prosty efekt wygładzający, dzięki czemu użytkownik nie dozna szoku po kliknięciu przycisku Do góry .

Jest bardzo mały, a po zminimalizowaniu staje się jeszcze mniejszy. Programiści szukający alternatywy dla metody jquery, ale chcący uzyskać te same wyniki, mogą spróbować tego.

JS

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>

Twoje zdrowie!


8

To działa dla mnie:

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

Używa skrótu setTimeoutwewnątrz elementu, onloadaby umożliwić przeglądarce przewinięcie.


Aby to zadziałało na moich przeglądarkach IE / Chrome / FF, muszę połączyć odpowiedź Niet Dark Absol i odpowiedź user113716 (używając limitu czasu).
Panini Luncher

@Panini: twoja sugestia działa dla mnie na Chrome / FF, ale nie IE11.
EML

8

Możesz używać z jQuery

jQuery(window).load(function(){

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

});

To jest w zasadzie to, co W KOŃCU znalazłem do pracy na CentOS 6.7 przy użyciu FF 45.1.0. Moja nieco inna wersja (opakowana w funkcję ładowania okna) to: $ ("html, body"). Animate ({scrollTop: 0}, 1);
Brandon Elliott

6

Użyj następującej funkcji

window.scrollTo(xpos, ypos)

Tutaj wymagane są xpos. Współrzędna do przewinięcia wzdłuż osi X (poziomej), w pikselach

ypos jest również wymagane. Współrzędna do przewinięcia wzdłuż osi Y (w pionie) w pikselach


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

Użyj tego


Miły! Działa dobrze z animacją!
Sakthivel

4

Poniższy kod działa w przeglądarkach Firefox, Chrome i Safari , ale nie udało mi się to przetestować w przeglądarce Internet Explorer. Czy ktoś może to przetestować, a następnie edytować moją odpowiedź lub skomentować ją?

$(document).scrollTop(0);

4

Moje czyste (animowane) rozwiązanie JavaScript:

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

Wyjaśnienie:

window.scrollY to zmienna utrzymywana przez przeglądarkę, określająca ilość pikseli od góry, o jaką przewijano okno.

window.scrollTo(x,y) to funkcja, która przewija okno o określoną liczbę pikseli na osi x i osi y.

W ten sposób window.scrollTo(0,window.scrollY-20)przesuwa stronę o 20 pikseli w górę.

setTimeoutWywołuje funkcję ponownie w 10 milisekund, dzięki czemu możemy następnie przenieść go kolejne 20 pikseli (animowane) oraz ifkontrole instrukcji jeśli wciąż musimy zwoju.


3

Dlaczego nie użyjesz po prostu elementu referencyjnego na samym początku pliku HTML, np.

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

a kiedy strona się załaduje, po prostu zrób

$(document).ready(function(){

    top.location.href = '#top';

});

Jeśli przeglądarka przewinie się po uruchomieniu tej funkcji, po prostu to zrobisz

$(window).load(function(){

    top.location.href = '#top';

});

3
to zadziałało dla mnie, ale dodaje # top w adresie URL, czy możesz mi powiedzieć, jak mogę tego uniknąć, ale jednocześnie bez kompromisów z funkcjonalnością
Abbas

3

Przewiń do góry w różnych przeglądarkach:

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

Przewiń w różnych przeglądarkach do elementu z 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

Aby odpowiedzieć na edytowane pytanie, możesz zarejestrować program onscrollobsługi w następujący sposób:

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

To sprawi, że pierwsza próba przewijania (prawdopodobnie wykonana automatycznie przez przeglądarkę) zostanie skutecznie anulowana.


Niezłe rozwiązanie - spróbuję
Yarin

2

Jeśli jesteś w trybie dziwactw (dzięki @Niet the Dark Absol):

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

Jeśli jesteś w trybie ścisłym:

document.documentElement.scrollTop = 0;

Nie ma tu potrzeby jQuery.


2

To działa:

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

2

W moim przypadku ciało nie działało:

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

Ale HTML działał:

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

1
Dodaj obie 'html','body'jako nowoczesne przeglądarki FF, Chrome będzie przewijać na podstawie treści, ale IE8 i poniżej będą przewijały się tylko z'html','body'
Rajesh

2

Pomogło mi połączenie tych dwóch. Żadna z pozostałych odpowiedzi nie pomogła mi, ponieważ miałem sidenav, który nie przewijał.

 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

Jeśli ktoś korzysta z kątowego i materiałowego projektu z sidenavem. Spowoduje to przeniesienie na górę strony:

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 hash powinien załatwić sprawę. Jeśli masz nagłówek, możesz użyć

window.location.href = "#headerid";

w przeciwnym razie sam # zadziała

window.location.href = "#";

A gdy zostanie zapisany w adresie URL, pozostanie, jeśli odświeżysz.

W rzeczywistości nie potrzebujesz JavaScript do tego, aby zrobić to na zdarzeniu onclick, powinieneś po prostu umieścić link wokół elementu i nadać mu # jako href.


Przy okazji, window.location nie jest częścią drzewa, więc jest teraz używane, aby czekać na załadowanie.
xavierm02

0

Najpierw dodaj pusty tag kotwicy do miejsca, w którym chcesz się udać

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

Teraz dodaj funkcję w sekcji nagłówka

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

na koniec dodaj zdarzenie onload do tagu body

<body onload="GoToTop()">

0

Ogólna wersja, która działa dla dowolnej wartości X i Y i jest taka sama jak interfejs API window.scrollTo, tylko z dodatkiem scrollDuration.

* Ogólna wersja pasująca do interfejsu API przeglądarki window.scrollTo **

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

Pamiętam, że widziałem ten opublikowany gdzie indziej (nie mogłem znaleźć miejsca), ale działa to naprawdę dobrze:

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

To dziwne, ale sposób, w jaki to działa, zależy od sposobu, w jaki działa kolejka stosu JavaScript. Pełne wyjaśnienie można znaleźć tutaj w sekcji Zero opóźnień.

Podstawową ideą jest to, że czas setTimeoutnie określa w rzeczywistości ustawionej ilości czasu, który będzie czekać, ale minimalny czas, który będzie czekać. Więc kiedy każesz mu czekać 0 ms, przeglądarka uruchamia wszystkie inne procesy w kolejce (jak przewijanie okna do miejsca, w którym byłeś ostatnio), a następnie wykonuje wywołanie zwrotne.


-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
Witamy w stackoverflow. Oprócz podanego kodu spróbuj wyjaśnić, dlaczego i jak to rozwiązuje problem.
jtate
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.