Comment obtenir la position de la barre de défilement avec Javascript?

203

J'essaie de détecter la position de la barre de défilement du navigateur avec JavaScript pour décider où dans la page se trouve la vue actuelle. Je suppose que je dois détecter où se trouve le pouce sur la piste, puis la hauteur du pouce en pourcentage de la hauteur totale de la piste. Est-ce que je complique trop les choses ou est-ce que JavaScript offre une solution plus simple que cela? Des idées au niveau du code?

Paul
la source

Réponses:

219

Vous pouvez utiliser element.scrollTopet element.scrollLeftpour obtenir respectivement le décalage vertical et horizontal qui a été défilé. elementpeut être document.bodysi vous vous souciez de la page entière. Vous pouvez le comparer à element.offsetHeightet element.offsetWidth(encore une fois, elementpeut être le corps) si vous avez besoin de pourcentages.

Max Shawabkeh
la source
2
Quel navigateur utilisez-vous? Obtenir le corps se fait différemment dans différents navigateurs ( elementet document.bodyn'étaient que des exemples). Voir howtocreate.co.uk/tutorials/javascript/browserwindow pour plus de détails.
Max Shawabkeh
8
Je l'ai obtenu pour me donner la valeur correcte sur Firefox 3.6 avec window.pageYOffset, mais je ne peux rien faire fonctionner sur IE7. Essayé window.pageYOffset, document.body.scrollTop, document.documentElement.scrollTop,element.scrollTop
Paul
1
scrollTop n'a fonctionné pour moi que lorsque j'ai ajouté des crochets ... $ (". scrollBody"). scrollTop ()
maia
9
Si vous avez affaire à l'élément 'window', vous pouvez utiliser window.scrollY au lieu de window.scrollTop
Janis Jansen
6
Je pense que la position de défilement n'est pas activée document.bodydans la plupart des navigateurs modernes - elle est généralement activée document.documentElementmaintenant. Voir bugs.chromium.org/p/chromium/issues/detail?id=157855 pour la transition de Chrome.
fzzfzzfzz
144

Je l'ai fait pour un <div>Chrome.

element .scrollTop - sont les pixels cachés en haut en raison du défilement. Sans défilement, sa valeur est 0.

element .scrollHeight - correspond aux pixels de la division entière.

element .clientHeight - sont les pixels que vous voyez dans votre navigateur.

var a = element.scrollTop;

sera la position.

var b = element.scrollHeight - element.clientHeight;

sera la valeur maximale de scrollTop .

var c = a / b;

sera le pourcentage de défilement [de 0 à 1] .

Gatsby
la source
3
C'est presque vrai. pour var b, vous devriez soustraire window.innerHeight et non element.clientHeight.
Kahless
52
document.getScroll = function() {
    if (window.pageYOffset != undefined) {
        return [pageXOffset, pageYOffset];
    } else {
        var sx, sy, d = document,
            r = d.documentElement,
            b = d.body;
        sx = r.scrollLeft || b.scrollLeft || 0;
        sy = r.scrollTop || b.scrollTop || 0;
        return [sx, sy];
    }
}

renvoie un tableau avec deux entiers- [scrollLeft, scrollTop]

Kennebec
la source
4
Montrer comment utiliser cette fonction avec un exemple aurait été formidable.
user18490
1
Je suppose que vous pouvez utiliser ce lastscroll = getScroll (); window.scrollTo (lastscroll [0], lastscroll [1]);
Dinesh Rajan
Fonctionne très bien mais j'ai changé le retour à un objet avec les touches x et y car cela a un peu plus de sens pour moi.
xd6_
Modifié suite au commentaire de @ user18490.
Davide Cannizzo
ReferenceError: Impossible de trouver la variable: element
Jonny
36

C'est comme ça :)

window.addEventListener("scroll", (event) => {
    let scroll = this.scrollY;
    console.log(scroll)
});
Pasteur Brayan
la source
13

Réponse pour 2018 :

La meilleure façon de faire des choses comme ça est d'utiliser l' API Intersection Observer .

L'API Intersection Observer fournit un moyen d'observer de manière asynchrone les modifications à l'intersection d'un élément cible avec un élément ancêtre ou avec la fenêtre d'affichage d'un document de niveau supérieur.

Historiquement, la détection de la visibilité d'un élément, ou de la visibilité relative de deux éléments l'un par rapport à l'autre, a été une tâche difficile pour laquelle les solutions ont été peu fiables et sujettes à ralentir le navigateur et les sites auxquels l'utilisateur accède. Malheureusement, à mesure que le Web a mûri, le besoin de ce type d'informations s'est accru. Les informations d'intersection sont nécessaires pour de nombreuses raisons, telles que:

  • Le chargement paresseux d'images ou d'autres contenus pendant qu'une page défile.
  • Implémentation de sites Web à «défilement infini», où de plus en plus de contenu est chargé et rendu au fur et à mesure que vous faites défiler, afin que l'utilisateur n'ait pas à parcourir les pages.
  • Reporting de visibilité des publicités afin de calculer les revenus publicitaires.
  • Décider d'exécuter ou non des tâches ou des processus d'animation selon que l'utilisateur verra ou non le résultat.

L'implémentation de la détection d'intersection dans le passé impliquait des gestionnaires d'événements et des boucles appelant des méthodes telles que Element.getBoundingClientRect () pour générer les informations nécessaires pour chaque élément affecté. Étant donné que tout ce code s'exécute sur le thread principal, même l'un d'entre eux peut entraîner des problèmes de performances. Lorsqu'un site est chargé avec ces tests, les choses peuvent devenir carrément laides.

Consultez l'exemple de code suivant:

var options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

var observer = new IntersectionObserver(callback, options);

var target = document.querySelector('#listItem');
observer.observe(target);

La plupart des navigateurs modernes prennent en charge IntersectionObserver , mais vous devez utiliser le polyfill pour la compatibilité descendante.

str
la source
9

si vous vous souciez de la page entière. vous pouvez utiliser ceci:

document.body.getBoundingClientRect().top

lemospy
la source
1
utilisez plutôt document.body
danial dezfouli
4

Si vous utilisez jQuery, il existe une fonction parfaite pour vous: .scrollTop ()

doc ici -> http://api.jquery.com/scrollTop/

remarque: vous pouvez utiliser cette fonction pour récupérer OU définir la position.

voir aussi: http://api.jquery.com/?s=scroll

Simon le saumon
la source
26
Pourquoi répondre à une question sur JS avec une bibliothèque pour JS, alors qu'il est tout à fait possible et même pratique de le faire en JS brut? Vous lui demandez simplement d'ajouter du temps de chargement supplémentaire et d'utiliser du stockage pour quelque chose de complètement inutile. Aussi, depuis quand javascript a-t-il commencé à signifier JQuery?
4
si vous demandez individuellement, je n'ai jamais aimé jQuery et je n'ai pas répondu à cette question, mais dans Vanilla JS, il y a déjà des réponses données par d'autres gars, alors quel est le problème si quelqu'un a ajouté une épice savoureuse dans ce fil. (Il a déjà mentionné que si vous utilisez jQuery)
Ravinder Payal
@ R01010010 c'est parce que de nos jours, JQuery est inutile et contre-productif, toutes les fonctionnalités de JQuery sont faciles à implémenter avec VanilaJS, vous devenez également dépendant de ce qui est à l'intérieur de JQuery, avec de nouvelles fonctionnalités disponibles dans VanillsaJS, vous en tant que programmeur, ne vous mettrez pas à jour, juste à titre d'exemple , de nos jours, il y a une nouvelle API dans VanillaJS appelée fetch qui a remplacé l'ancien XHR, si vous étiez juste dans le monde de JQuery, vous ne verrez jamais les avantages de fetch et continuer à utiliser jQuery.ajax (). Mon opinion personnelle est que les gens qui continuent en utilisant JQuery, c'est parce qu'ils ont arrêté d'apprendre. VanillaJS est également plus rapide vanilla-js.com
John Balvin Arias
@JohnBalvinArias parle de fetch, que se passe-t-il sur ie11 ou même Edge?
Ben
Corrigez-moi si je me trompe, mais fetch ne fonctionne pas correctement sur "moderne" c'est-à-dire, et c'est encore largement utilisé. Si j'utilisais jquery, je ne serais guère encouragé à passer à autre chose
Ben
3

Voici l'autre façon d'obtenir la position de défilement

const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
Gor
la source
0

Je pense que la fonction suivante peut aider à avoir des valeurs de coordonnées de défilement:

const getScrollCoordinate = (el = window) => ({
  x: el.pageXOffset || el.scrollLeft,
  y: el.pageYOffset || el.scrollTop,
});

J'ai eu cette idée de cette réponse avec un petit changement.

AmerllicA
la source