JavaScript pour faire défiler une longue page vers DIV

106

J'ai un lien sur une longue page HTML. Quand je clique dessus, je souhaite undiv autre partie de la page soit visible dans la fenêtre en faisant défiler la vue.

Un peu comme EnsureVisible dans d'autres langues.

J'ai vérifié scrollTopetscrollTo mais ils semblent être des harengs rouges.

Quelqu'un peut-il aider?

ɢʀᴜɴᴛ
la source

Réponses:

378

vieille question, mais si quelqu'un trouve cela via google (comme je l'ai fait) et qui ne veut pas utiliser d'ancres ou jquery; il y a une fonction javascript intégrée pour «sauter» vers un élément;

document.getElementById('youridhere').scrollIntoView();

et ce qui est encore mieux; selon les grandes tables de compatibilité sur quirksmode, ceci est pris en charge par tous les principaux navigateurs !

futtta
la source
2
Pas du tout un défilement fluide (du moins sur Firefox) mais cela fonctionne, avec une ligne de code, sans trucs tiers. Agréable.
MatrixFrog
Le problème avec le défilement intégré dans la vue est que lorsque vous regardez une longue page, l'utilisateur peut se perdre lorsque vous faites défiler la page. J'ai écrit une version animée de cette fonctionnalité qui fait défiler le conteneur uniquement lorsque cela est nécessaire et le fait avec une animation afin que l'utilisateur puisse réellement voir ce qui s'est passé. Il peut également exécuter une fonction complète par la suite. C'est similaire au plugin scrollTo jQuery à l'exception du fait que vous n'avez pas besoin de fournir un ancêtre scrollable. Il le recherche automatiquement.
Robert Koritnik
2
@Robert, cela semble fantastique. Pouvez-vous fournir un lien ou peut-être fournir une réponse qui inclut le code?
Kirk Woll
La simplicité de ceci est impressionnante.
MeanMatt
4
Pour les personnes à la recherche d'animation ou de défilement fluide:document.getElementById('#something').scrollIntoView({ behavior: 'smooth', block: 'center' });
Khalil Laleh
23

Si vous ne souhaitez pas ajouter d'extension supplémentaire, le code suivant devrait fonctionner avec jQuery.

$('a[href=#target]').
    click(function(){
        var target = $('a[name=target]');
        if (target.length)
        {
            var top = target.offset().top;
            $('html,body').animate({scrollTop: top}, 1000);
            return false;
        }
    });
Josh
la source
22

Que diriez-vous du JQuery ScrollTo - voir cet exemple de code

George Mauer
la source
24
JQuery n'est-il pas javascript ou voulons-nous écrire toutes les bibliothèques à partir de zéro? Ma lecture de la question était de savoir comment implémenter une fonctionnalité spécifique, peut-être voulait-il connaître les détails techniques, mais vous ne le savez pas plus que moi.
George Mauer
4
@BjornTipling - s'il voulait voir le JavaScript ici, c'est demos.flesler.com/jquery/scrollTo/js/jquery.scrollTo-min.js
Norman H
15
<a href="#myAnchorALongWayDownThePage">Click here to scroll</a>

<A name='myAnchorALongWayDownThePage"></a>

Pas de défilement sophistiqué mais cela devrait vous y emmener.

mjallday
la source
La question demandait à javascript d'accomplir la même chose.
Scott Swezey
3
Vérifiez la réponse de Peter Boughton dans stackoverflow.com/questions/66964 - donner au div un identifiant au lieu d'utiliser des ancres nommées fonctionne de la même manière, mais a une bien meilleure signification sémantique et nécessite moins de balisage.
nickf
comme scott s souligné ci-dessous: document.location.hash = "myAnchor";
Aaron Watters
8

La difficulté avec le défilement est que vous devrez peut-être non seulement faire défiler la page pour afficher un div, mais vous devrez peut-être aussi faire défiler les divs défilables sur n'importe quel nombre de niveaux.

La propriété scrollTop est disponible sur n'importe quel élément DOM, y compris le corps du document. En le définissant, vous pouvez contrôler jusqu'où quelque chose défile. Vous pouvez également utiliser les propriétés clientHeight et scrollHeight pour voir combien de défilement est nécessaire (le défilement est possible lorsque clientHeight (fenêtre) est inférieur à scrollHeight (la hauteur du contenu).

Vous pouvez également utiliser la propriété offsetTop pour déterminer où se trouve un élément dans le conteneur.

Pour créer une routine de "défilement dans la vue" vraiment générale à partir de zéro, vous devez commencer au nœud que vous souhaitez exposer, vous assurer qu'il est dans la partie visible de son parent, puis répéter la même chose pour le parent, etc. le chemin jusqu'à ce que vous atteigniez le sommet.

Une étape de ceci ressemblerait à ceci (code non testé, ne vérifiant pas les cas de bord):

function scrollIntoView(node) {
  var parent = node.parent;
  var parentCHeight = parent.clientHeight;
  var parentSHeight = parent.scrollHeight;
  if (parentSHeight > parentCHeight) {
    var nodeHeight = node.clientHeight;
    var nodeOffset = node.offsetTop;
    var scrollOffset = nodeOffset + (nodeHeight / 2) - (parentCHeight / 2);
    parent.scrollTop = scrollOffset;
  }
  if (parent.parent) {
    scrollIntoView(parent);
  }
}
Levik
la source
8

Vous pouvez utiliser la Element.scrollIntoView()méthode mentionnée ci-dessus. Si vous le laissez sans paramètres à l'intérieur, vous aurez un défilement instantané . Pour éviter cela, vous pouvez ajouter ce paramètre - behavior:"smooth".

Exemple:

document.getElementById('scroll-here-plz').scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});

Remplacez simplement scroll-here-plzpar votre divélément ou sur un site Web. Et si vous voyez votre élément en bas de votre fenêtre ou si la position n'est pas ce à quoi vous vous attendiez, jouez avec le paramètre block: "". Vous pouvez utiliser block: "start", block: "end"ou block: "center".

N'oubliez pas: utilisez toujours des paramètres à l'intérieur d'un objet {}.

Si vous rencontrez toujours des problèmes, accédez à https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

Il existe une documentation détaillée pour cette méthode.

Smelino
la source
7

Cela a fonctionné pour moi

document.getElementById('divElem').scrollIntoView();
Xcoder
la source
5

Réponse publiée ici - même solution à votre problème.

Edit: la réponse JQuery est très agréable si vous voulez un défilement fluide - je n'avais pas vu cela en action auparavant.

Mandrin
la source
4

Pourquoi pas une ancre nommée?

Limier
la source
Hé ... j'ai commencé à publier une solution JavaScript, puis j'ai lu la vôtre ... et je me suis giflé. Bon travail! :-)
Shog9
4

La propriété dont vous avez besoin est location.hash. Par exemple:

location.hash = 'top'; // sauterait à l'ancre nommée "en haut

Je ne sais pas comment faire la belle animation de défilement sans utiliser le dojo ou une boîte à outils comme celle-là, mais si vous en avez juste besoin pour sauter à une ancre, location.hash devrait le faire.

(testé sur FF3 et Safari 3.1.2)

Scott Swezey
la source
1
Excellente solution simple ... fonctionne également avec IE6 et IE8 (non testé avec IE7)
ckarras
2
C'est de loin la meilleure réponse; c'est simple, fiable et ne nécessite aucune bibliothèque. +1
4

Je ne peux pas ajouter de commentaire à la réponse de futtta ci-dessus, mais pour une utilisation plus fluide du défilement:

onClick="document.getElementById('more').scrollIntoView({block: 'start', behavior: 'smooth'});"
poisson drôle
la source
Fonctionne parfaitement dans Chrome. Merci!
Al Belmondo
0

scrollTop (IIRC) est l'endroit où, dans le document, le haut de la page est défilé. scrollTo fait défiler la page de sorte que le haut de la page soit là où vous spécifiez.

Ce dont vous avez besoin ici, ce sont des styles manipulés par Javascript. Dites si vous voulez que le div soit hors de l'écran et que vous faites défiler à partir de la droite, vous définiriez l'attribut gauche du div à la largeur de la page, puis le réduirez d'une quantité définie toutes les quelques secondes jusqu'à ce qu'il soit où vous le souhaitez.

Cela devrait vous orienter dans la bonne direction.

Supplémentaire: je suis désolé, je pensais que vous vouliez qu'un div distinct apparaisse quelque part (un peu comme ce site le fait parfois), et ne déplacez pas la page entière vers une section. Une utilisation appropriée des ancres permettrait d'atteindre cet effet.

Benjamin Autin
la source
0

Il existe un plugin jQuery pour le cas général du défilement vers un élément DOM, mais si les performances sont un problème (et quand ne l'est-il pas?), Je suggérerais de le faire manuellement. Cela implique deux étapes:

  1. Recherche de la position de l'élément vers lequel vous faites défiler.
  2. Faire défiler jusqu'à cette position.

quirksmode donne une bonne explication du mécanisme derrière le premier. Voici ma solution préférée:

function absoluteOffset(elem) {
    return elem.offsetParent && elem.offsetTop + absoluteOffset(elem.offsetParent);
}

Il utilise la conversion de null à 0, ce qui n'est pas une étiquette appropriée dans certains cercles, mais j'aime ça :) La deuxième partie utilise window.scroll. Le reste de la solution est donc:

function scrollToElement(elem) {
    window.scroll(absoluteOffset(elem));
}

Voila!

Andrey Fedorov
la source
vous avez oublié de définir le premier paramètre - window.scroll (0, absoluteOffset (elem));
Richard
0

J'ai personnellement trouvé que la réponse basée sur jQuery de Josh ci-dessus était la meilleure que j'ai vue et fonctionnait parfaitement pour mon application ... bien sûr, j'étais déjà jQuery ... je n'aurais certainement pas inclus toute la bibliothèque jQ juste pour cela un seul but.

À votre santé!

EDIT: OK ... donc quelques secondes après avoir posté ceci, j'ai vu une autre réponse juste dessous mienne ( ne sais pas si elle est toujours en dessous de moi après une modification) qui disait d'utiliser:

document.getElementById ('votre_ID_élément_ici'). scrollIntoView ();

Cela fonctionne parfaitement et dans tellement moins de code que la version jQuery! Je n'avais aucune idée qu'il y avait une fonction intégrée dans JS appelée .scrollIntoView (), mais c'est là! Donc, si vous voulez une animation sophistiquée, allez à jQuery. Rapide et sale ... utilisez celui-ci!

Lelando
la source
0

Pour un défilement fluide, ce code est utile

$('a[href*=#scrollToDivId]').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      var head_height = $('.header').outerHeight(); // if page has any sticky header get the header height else use 0 here
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top - head_height
        }, 1000);
        return false;
      }
    }
  });
Swarnendu Paul
la source
-2

Corrigez-moi si je me trompe mais je lis la question encore et encore et je pense toujours qu'Angus McCoteup demandait comment définir un élément pour être position: fixe.

Angus McCoteup, consultez http://www.cssplay.co.uk/layouts/fixed.html - si vous voulez que votre DIV se comporte comme un menu là-bas, jetez un œil à un CSS ici

Vitaly Sharovatov
la source