scrollIntoView Scrolls trop loin

j'ai une page où une barre de défilement contenant des lignes de table avec des divs est générée dynamiquement à partir de la base de données. Chaque rangée de tableaux agit comme un lien, un peu comme vous le verriez sur une liste de lecture YouTube à côté du lecteur vidéo.

Lorsqu'un utilisateur visite la page, l'option sur laquelle il se trouve est censée aller en haut de la div de défilement. Cette fonctionnalité fonctionne. Le problème, c'est qu'il va un peu trop loin. Comme l'option ils sont sur est d'environ 10px trop élevé. Donc, la page est visité, l'url est utilisée pour identifier l'option a été sélectionnée, puis défile que l'option vers le haut de la div défilement. Remarque: Ce n'est pas la barre de défilement de la fenêtre, c'est un div avec une barre de défilement.

j'utilise ce code pour faire bouger l'option sélectionnée vers le haut de la div:

var pathArray = window.location.pathname.split( '/' );

var el = document.getElementById(pathArray[5]);

el.scrollIntoView(true);

il le déplace vers le haut de la div mais environ 10 pixels trop haut. Quelqu'un sait comment résoudre ce problème?

27
demandé sur Matthew Wilson 2014-07-10 04:09:42

7 réponses

si c'est environ 10px, alors je suppose que vous pouvez simplement régler manuellement le contenant div's défiler décalage comme ça:

el.scrollIntoView(true);
document.getElementById("containingDiv").scrollTop += 10;
27
répondu Lucas Trzesniewski 2014-07-10 00:16:18

Vous pouvez le faire en deux étapes :

el.scrollIntoView(true);
window.scrollBy(0, -10); // Adjust scrolling with a negative value here
36
répondu fred727 2017-02-05 20:22:47

Vous pouvez également utiliser le element.scrollIntoView() options

el.scrollIntoView(
  { 
    behavior: 'smooth', 
    block: 'start' 
  },
);

que la plupart des navigateurs soutien

7
répondu Nicholas Murray 2018-04-07 18:50:11

Position De L'Ancre Par La Méthode Absolue

une autre façon de faire ceci est de positionner vos ancres exactement où vous voulez sur la page plutôt que de compter sur le défilement par offset. Je trouve qu'il permet un meilleur contrôle pour chaque élément (par exemple. si vous voulez un décalage différent pour certains éléments), et peut également être plus résistant aux changements/différences de L'API du navigateur.

<div id="title-element" style="position: relative;">
  <div id="anchor-name" style={{ position: 'absolute', top: -100, left: 0 }} />
</div>

Maintenant, le décalage est spécifié comme -100 par rapport à l'élément. Créer une fonction pour créer cette ancre pour réutiliser du code, ou si vous utilisez un cadre js moderne tel que React le faire en créant un composant qui rend votre ancre, et passer dans le nom d'ancre et l'alignement pour chaque élément, qui peut ou ne peut pas être le même.

alors il suffit d'utiliser :

const element = document.getElementById('anchor-name')
element.scrollIntoView({ behavior: 'smooth', block: 'start' });

pour le défilement en douceur avec un décalage de 100px.

3
répondu Steve Banton 2018-10-04 13:48:17

en me basant sur une réponse précédente, je fais ceci dans un projet Angular5.

commencé par:

// el.scrollIntoView(true);
el.scrollIntoView({
   behavior: 'smooth',
   block: 'start'
});
window.scrollBy(0, -10); 

mais cela a donné quelques problèmes et a nécessité de définir timeout pour le scrollBy () comme ceci:

//window.scrollBy(0,-10);
setTimeout(() => {
  window.scrollBy(0,-10)
  }, 500);

+1 à Fred727 pour cette solution simple mais efficace.

2
répondu PrimaryW 2018-08-20 16:38:13

je l'ai et il fonctionne à merveille pour moi:

// add a smooth scroll to element
scroll(el) {
el.scrollIntoView({
  behavior: 'smooth',
  block: 'start'});

setTimeout(() => {
window.scrollBy(0, -40);
}, 500);}

j'Espère que ça aide.

1
répondu Fernando Brandao 2018-09-20 15:32:00

en supposant que vous voulez faire défiler vers les divs qui sont tous au même niveau dans DOM et ont le nom de classe "scroll-with-offset", alors ce CSS résoudra le problème:

.scroll-with-offset {    
  padding-top: 100px;
  margin-bottom: -100px;
}

décalage dans le haut de la page est 100px. Il ne fonctionne comme prévu avec le bloc: "démarrer":

element.scrollIntoView({ behavior: 'smooth', block: 'start' });

ce qui se passe, c'est que le point supérieur des divs est à l'emplacement normal, mais leur contenu intérieur commence à 100px sous l'emplacement normal. C'est à ça que sert padding-top:100px. marge-bottom: - 100px est de compenser la marge supplémentaire de div ci-dessous. Pour que la solution soit complète, ajoutez aussi ce CSS pour compenser les marges / paddings pour les divs les plus hauts et les plus bas:

.top-div {
  padding-top: 0;
}
.bottom-div {
  margin-bottom: 0;
}
0
répondu George P 2018-08-23 07:58:06