Comment faire défiler vers le haut de la page avec JavaScript / jQuery?


159

Existe-t-il un moyen de contrôler le défilement du navigateur avec JavaScript / jQuery?

Lorsque je fais défiler ma page à mi-chemin, puis que je déclenche un rechargement, je veux que la page aille vers le haut, mais à la place, elle essaie de trouver la dernière position de défilement. Alors j'ai fait ceci:

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

Mais pas de chance.

MODIFIER :

Donc, vos deux réponses ont fonctionné lorsque je les ai appelées après le chargement de la page - Merci. Cependant, si je fais juste une actualisation sur la page, on dirait que le navigateur calcule et défile jusqu'à son ancienne position de défilement APRÈS l' .readyévénement (j'ai également testé la fonction onload () du corps).

Le suivi est donc: y a-t-il un moyen d'empêcher le navigateur de défiler jusqu'à sa position passée ou de faire défiler à nouveau vers le haut APRÈS qu'il ait fait son travail?


1
Que se passe-t-il lorsque vous le faites à partir de $ (window) .load ()?
mpdonadio

2
@ MPD- Excellente idée! ... mais juste essayé et le réglage du défilement se produit toujours après cela. Merci pour le conseil cependant, cela aide en fait à une autre de mes questions: stackoverflow.com/questions/4210829/… . Si vous voulez répondre à cette question, je vais vous donner quelques conseils.
Yarin

@Yarin Désolé, vous avez dû attendre 9 ans pour cela. Vous devez définir history.scrollRestoration avant d'essayer de faire défiler. Voyez ma réponse.
RayLoveless

Réponses:


17

Wow, j'ai 9 ans de retard sur cette question. Voici:

Ajoutez ce code à votre 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);

Prise en charge du navigateur history.scrollRestoration:

Chrome: pris en charge (depuis 46)

Firefox: pris en charge (depuis 46)

IE / Edge: non pris en charge (encore ..)

Opera: pris en charge (depuis 33)

Safari: pris en charge

Pour IE / Edge, si vous souhaitez faire défiler à nouveau vers le haut APRÈS qu'il défile automatiquement, cela a fonctionné pour moi:

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

Merci @RayLoveless - malheureusement, cela n'est pas pris en charge par les navigateurs MS (car bien sûr). Voir caniuse.com/#feat=mdn-api_history_scrollrestoration et developer.mozilla.org/de/docs/Web/API
...

@Yarin, bon point. J'ai mis à jour mon message. Est-ce que ça répond à votre question?
RayLoveless

312

Solution multi-navigateur, pure JavaScript:

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

3
Puisque vous utilisez jQuery, vous pouvez essayer ceci:$(window).one("scroll",function() { /* the code from my answer here */ });
Niet the Dark Absol

Pour que cela fonctionne sur mes navigateurs croisés IE / Chrome / FF, je dois combiner la réponse Niet Dark Absol et la réponse user113716 (en utilisant le délai d'expiration).
Panini Luncher

Ne fonctionnait pas sur CentOS 6.7 avec FF 45.1.0. Je l'ai enveloppé dans un document, prêt juste pour être sûr.
Brandon Elliott

Je veux juste souligner que, d'après mes tests (sur les versions modernes / 2018 de chrome incluses), cette solution fonctionne de manière plus fiable
mattLummus

Cela n'empêche pas le navigateur de défiler jusqu'à sa position passée. Voyez ma réponse.
RayLoveless

85

Vous presque l' avez - vous devez régler le scrollTopsur body, non window:

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

ÉDITER:

Vous pouvez peut-être ajouter une ancre vierge en haut de la page:

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

3
J'ai essayé cela aujourd'hui et n'a pas fonctionné dans FF16. En utilisant pur JS, vu plus bas sur cette page, à la place: document.body.scrollTop = document.documentElement.scrollTop = 0;
Gigi2m02

2
Le code ci-dessus fonctionnera correctement dans les navigateurs modernes comme FF, Chrome mais il ne fonctionnera pas dans IE8 et ci-dessous, essayez d'ajouter les deux 'html','body'car les navigateurs modernes défileront en fonction du corps, mais IE8 et ci-dessous ne défileront qu'avec 'html', 'body'
Rajesh

17

Existe-t-il un moyen d'empêcher le navigateur de défiler jusqu'à sa position passée ou de faire défiler à nouveau vers le haut APRÈS qu'il ait fait son travail?

La solution jquery suivante fonctionne pour moi:

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

oui faites défiler vers le haut avant le rafraîchissement
Morgan T.

Pas complètement multi-navigateur, mais fonctionne toujours pour la plupart. Associé à certaines des autres réponses, c'est un bon ajout
Brad Decker

16

Voici une version de défilement animé purement JavaScript pour les utilisateurs de no-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);
};

Puis:

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

1
Cool. Cependant, je préférerais requestAnimationStepplutôt que setTimeout. De plus, cela ne répond pas à la question d'OP.
Quentin Roy

mis en œuvre cela dans Angular. fonctionne comme un charme. Merci
Ahmad

12

METTRE À JOUR

Aller en haut de la page avec un effet de défilement est un peu plus facile en javascript maintenant avec:

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

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

MISE EN GARDE

Nous l'avons utilisé dans nos projets les plus récents, mais je viens de vérifier la documentation mozilla en ce moment tout en mettant à jour ma réponse et je pense qu'elle a été mise à jour. En ce moment , la méthode est window.scroll(x-coord, y-coord)et ne mentionne pas d' exemples ou de montrer qui utilisent le objectparamètre où vous pouvez définir le behaviorà smooth. Je viens d'essayer le code et cela fonctionne toujours dans Chrome et Firefox et le paramètre d'objet est toujours dans les spécifications .

Utilisez donc ceci avec prudence ou vous pouvez utiliser ce Polyfill . Mis à part le défilement vers le haut, ce polyfill gère également d' autres méthodes: window.scrollBy, element.scrollIntoView, etc.


ANCIENNE RÉPONSE

Ceci est notre javascriptimplémentation vanille . Il a un simple effet d'accélération afin que l'utilisateur ne soit pas choqué après avoir cliqué sur le bouton Vers le haut .

Il est très petit et devient encore plus petit lorsqu'il est minifié. Les développeurs qui recherchent une alternative à la méthode jquery mais veulent les mêmes résultats peuvent essayer ceci.

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>

À votre santé!


8

Cela fonctionne pour moi:

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

Utilise un court setTimeoutà l'intérieur du onloadpour donner au navigateur une chance de faire le défilement.


Pour que cela fonctionne sur mes navigateurs croisés IE / Chrome / FF, je dois combiner la réponse Niet Dark Absol et la réponse user113716 (en utilisant le délai d'expiration).
Panini Luncher

@Panini: votre suggestion fonctionne pour moi sur Chrome / FF, mais pas IE11.
EML

8

Vous pouvez utiliser avec jQuery

jQuery(window).load(function(){

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

});

C'est essentiellement ce que j'ai finalement trouvé pour fonctionner sur CentOS 6.7 en utilisant FF 45.1.0. Ma version légèrement différente (enveloppée dans une fonction de chargement de fenêtre) est: $ ("html, body"). Animate ({scrollTop: 0}, 1);
Brandon Elliott

6

Utilisez la fonction suivante

window.scrollTo(xpos, ypos)

Ici, xpos est obligatoire. La coordonnée vers laquelle faire défiler, le long de l'axe des x (horizontal), en pixels

ypos est également obligatoire. La coordonnée vers laquelle faire défiler, le long de l'axe y (vertical), en pixels


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

Utilisez ceci


Agréable! Fonctionne bien avec l'animation!
Sakthivel

4

Le code suivant fonctionne dans Firefox, Chrome et Safari , mais je n'ai pas pu le tester dans Internet Explorer. Quelqu'un peut-il le tester, puis modifier ma réponse ou la commenter?

$(document).scrollTop(0);

4

Ma solution Javascript pure (animée):

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

Explication:

window.scrollY est une variable gérée par le navigateur de la quantité de pixels à partir du haut par laquelle la fenêtre a été défilée.

window.scrollTo(x,y) est une fonction qui fait défiler la fenêtre d'une quantité spécifique de pixels sur l'axe x et sur l'axe y.

Ainsi, window.scrollTo(0,window.scrollY-20)déplace la page de 20 pixels vers le haut.

La setTimeoutfonction appelle à nouveau la fonction dans 10 millisecondes afin que nous puissions la déplacer de 20 pixels supplémentaires (animée), et l' ifinstruction vérifie si nous devons encore faire défiler.


3

Pourquoi n'utilisez-vous pas simplement un élément de référence au tout début de votre fichier html, comme

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

puis, lorsque la page se charge, faites simplement

$(document).ready(function(){

    top.location.href = '#top';

});

Si le navigateur défile après le déclenchement de cette fonction, faites simplement

$(window).load(function(){

    top.location.href = '#top';

});

3
cela a fonctionné pour moi, mais cela ajoute le #top dans l'url, pouvez-vous s'il vous plaît me dire comment puis-je éviter cela, mais en même temps, sans faire de compromis avec la fonctionnalité
Abbas

3

Faites défiler les navigateurs vers le haut:

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

Faites défiler les navigateurs jusqu'à un élément avec 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

Pour répondre à votre question modifiée, vous pouvez enregistrer le onscrollgestionnaire comme ceci:

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

Cela fera en sorte que la première tentative de défilement (qui est probablement la tentative automatique effectuée par le navigateur) sera effectivement annulée.



2

Si vous êtes en mode quircks (merci @Niet the Dark Absol):

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

Si vous êtes en mode strict:

document.documentElement.scrollTop = 0;

Pas besoin de jQuery ici.


2

Cela fonctionne:

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

2

Dans mon cas, le corps n'a pas fonctionné:

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

Mais HTML a fonctionné:

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

1
Ajoutez les deux 'html','body'comme les navigateurs modernes FF, Chrome défilera en fonction du corps, mais IE8 et ci-dessous ne défileront qu'avec'html','body'
Rajesh

2

La combinaison de ces deux m'a aidé. Aucune des autres réponses ne m'a aidé car j'avais un sidenav qui ne défilait pas.

 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

Si quelqu'un utilise la conception angulaire et matérielle avec sidenav. Cela vous enverra en haut de la page:

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 le hachage devrait faire le travail. Si vous avez un en-tête, vous pouvez utiliser

window.location.href = "#headerid";

sinon, le # seul fonctionnera

window.location.href = "#";

Et comme il est écrit dans l'URL, il restera si vous actualisez.

En fait, vous n'avez pas besoin de JavaScript pour cela si vous voulez le faire sur un événement onclick, vous devriez simplement mettre un lien autour de votre élément et lui donner # comme href.


Btw, window.location ne fait pas partie de l'arborescence, il est donc maintenant utilisé pour attendre le chargement.
xavierm02

0

Ajoutez d'abord une balise d'ancrage vide à l'endroit où vous voulez aller

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

Maintenant, ajoutez une fonction dans la section d'en-tête

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

enfin ajouter un événement onload à la balise body

<body onload="GoToTop()">

0

Une version générique qui fonctionne pour toutes les valeurs X et Y, et qui est la même que l'api window.scrollTo, juste avec l'ajout de scrollDuration.

* Une version générique correspondant à l'api du navigateur 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

Je me souviens avoir vu cela publié ailleurs (je n'ai pas pu trouver où), mais cela fonctionne très bien:

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

C'est bizarre, mais la façon dont cela fonctionne est basée sur le fonctionnement de la file d'attente de pile de JavaScript. L'explication complète se trouve ici dans la section Zero Delays.

L'idée de base est que le temps pour setTimeoutne spécifie pas réellement la durée définie pour laquelle il attendra, mais le temps minimum pendant lequel il attendra. Ainsi, lorsque vous lui dites d'attendre 0 ms, le navigateur exécute tous les autres processus en file d'attente (comme faire défiler la fenêtre jusqu'à l'endroit où vous étiez en dernier), puis exécute le rappel.


-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
Bienvenue dans stackoverflow. En plus du code que vous avez fourni, essayez d'expliquer pourquoi et comment cela résout le problème.
jtate
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.