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?

Yarin
źródło
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.
} 
RayLoveless
źródło
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;
Niet the Dark Absol
źródło
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';
});
Jacob Relkin
źródło
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);
});
Matt
źródło
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>
ulfryk
źródło
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!

Jo E.
źródło
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.

user113716
źródło
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);

});
Chanderkesh Kumar
źródło
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

Shoaib Quraishi
źródło
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

Ekin Ertaç
źródło
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);
duży ślepy
źródło
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.

Toastrackenigma
źródło
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';

});
arik
źródło
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);
            }
        } 
Binod Kalathil
źródło
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.

Niet the Dark Absol
źródło
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.


źródło
2

To działa:

jQuery(document).ready(function() {
     jQuery("html").animate({ scrollTop: 0 }, "fast");
});
srdjanprpa
źródło
2

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

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

Ale HTML działał:

$('html').scrollTop(0);
Sachin Prasad
źródło
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);
shailesh gavathe
źródło
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;"/>
user3178603
źródło
1

bez animacji, tylko scroll(0, 0)(vanilla JS)

maxbellec
źródło
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;
    });
Helzgate
źródło
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.

xavierm02
źródło
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()">
Satii
źródło
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();
}
jamesmfriedman
źródło
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.

Greyson R.
źródło
-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>
Kenrick Humber
źródło
1
Witamy w stackoverflow. Oprócz podanego kodu spróbuj wyjaśnić, dlaczego i jak to rozwiązuje problem.
jtate