Comment faire défiler jusqu'à un élément spécifique à l'aide de jQuery?

252

J'ai une grande table avec une barre de défilement verticale. Je voudrais faire défiler jusqu'à une ligne spécifique dans ce tableau en utilisant jQuery / Javascript.

Existe-t-il des méthodes intégrées pour ce faire?

Voici un petit exemple pour jouer avec.

div {
    width: 100px;
    height: 70px;
    border: 1px solid blue;
    overflow: auto;
}
<div>
    <table id="my_table">
        <tr id='row_1'><td>1</td></tr>
        <tr id='row_2'><td>2</td></tr>
        <tr id='row_3'><td>3</td></tr>
        <tr id='row_4'><td>4</td></tr>
        <tr id='row_5'><td>5</td></tr>
        <tr id='row_6'><td>6</td></tr>
        <tr id='row_7'><td>7</td></tr>
        <tr id='row_8'><td>8</td></tr>
        <tr id='row_9'><td>9</td></tr>
    </table>
</div>

Misha Moroshko
la source

Réponses:

563

Mort simple. Aucun plugin nécessaire .

var $container = $('div'),
    $scrollTo = $('#row_8');

$container.scrollTop(
    $scrollTo.offset().top - $container.offset().top + $container.scrollTop()
);

// Or you can animate the scrolling:
$container.animate({
    scrollTop: $scrollTo.offset().top - $container.offset().top + $container.scrollTop()
});​

Voici un exemple de travail .

Documentation pourscrollTop .

James
la source
4
Si le conteneur a une barre de défilement, vous devrez tenir compte de scrollTop: scrollTo.offset (). Top - container.offset (). Top + container.scrollTop ()
claviska
1
Vous pouvez faire défiler la fenêtre entière avec $ (document) .scrollTop (valeur) - le code jquery sous-jacent résout les problèmes de navigateur pour vous.
Chris Moschini
7
Si vous voulez scrollTocentré plutôt qu'en haut:scrollTo.offset().top - container.offset().top + container.scrollTop() - (container.height()/2)
Mahn
7
element.scrollIntoView()- c'est tout ce qu'il faut. L'animation est standardisée. Voir developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
WickyNilliams
7
Notez qu'il y a un caractère "invisible" à la fin du bloc de code. Le caractère est considéré comme invalide dans Edge, chrome. - un copy-paster
Attacktive
114

Je me rends compte que cela ne répond pas au défilement dans un conteneur, mais les gens le trouvent utile:

$('html,body').animate({scrollTop: some_element.offset().top});

Nous sélectionnons à la fois html et body car le scroller de document peut être sur l'un ou l'autre et il est difficile de déterminer lequel. Pour les navigateurs modernes, vous pouvez vous en sortir $(document.body).

Ou, pour aller en haut de la page:

$('html,body').animate({scrollTop: 0});

Ou sans animation:

$(window).scrollTop(some_element.offset().top);

OU...

window.scrollTo(0, some_element.offset().top); // native equivalent (x, y)
Dominique
la source
bonjour @infensus pouvez-vous me donner un exemple pratique de cette cause, la mienne ne fonctionne pas? j'ai utilisé var section2 = $ ('# section-2'); $ ('html, body'). animate ({scrollTop: section2.offset (). top});
dll_onFire
Cela semble bien - êtes-vous sûr que la section 2 existe? faire console.log (section2.length); et assurez-vous qu'il n'est pas 0. Fera un exemple dans un peu.
Dominic
Pourquoi $('html,body')? Il n'a besoin que dans un conteneur spécifique. La réponse acceptée est meilleure pour moi. J'ai un cas similaire comme la question posée et votre réponse n'a pas fonctionné pour moi.
Petroff
2
@Petroff étrangement quand j'ai écrit cela, je n'ai pas remarqué que l'élément était dans un conteneur de défilement. Je vais laisser ma réponse telle quelle, car les gens viennent ici d'une recherche Google pour faire défiler le corps en raison du titre de la question
Dominic
30

Je suis d'accord avec Kevin et les autres, utiliser un plugin pour cela est inutile.

window.scrollTo(0, $("#element").offset().top);
Fredrik Stolpe
la source
Pour quelque chose qui devrait être si simple, j'ai passé beaucoup de temps sur d'autres solutions en ligne, mais cette simple doublure fait exactement ce dont j'ai besoin.
Laurence Cope
3
Il convient de noter que cette méthode fonctionne pour toute la fenêtre. Si vous souhaitez faire défiler le contenu qui a débordé: faites défiler, cela ne fonctionnera pas.
Jeremy
12

J'ai réussi à le faire moi-même. Pas besoin de plugins. Découvrez mon essentiel :

// Replace #fromA with your button/control and #toB with the target to which     
// You wanna scroll to. 
//
$("#fromA").click(function() {
    $("html, body").animate({ scrollTop: $("#toB").offset().top }, 1500);
});
lorddarq
la source
Votre contenu d'une ligne, avec animation, était exactement ce dont j'avais besoin. Merci!
Scott Smith
No need for any plugins?? Mais vous utilisez jQuery! C'est une énorme bibliothèque, pas même un plugin.
Vert
1
Je mentionne que vous n'avez pas besoin d'ajouter une référence en plus de la référence de la bibliothèque jquery. De plus, jquery est une sorte de standard de l'industrie. Pourquoi ne l'utiliseriez-vous pas? C'est probablement tout à fait faisable sans jquery, mais cela nécessiterait toujours que quelqu'un écrive beaucoup de code juste pour la partie d'analyse. Cela semble contre-productif. Et il était contre-productif d'écrire un plugin complet juste pour faire défiler vers un divin divin.
lorddarq
4

Vous pouvez utiliser la scrollIntoView()méthode en javascript. juste donnerid.scrollIntoView();

Par exemple

row_5.scrollIntoView();
Tamilarasi
la source
Comment l'animer?
Vert
Pas besoin d'animer. Lorsque vous utilisez scrollIntoView (), le contrôle défilera automatiquement pour le faire apparaître dans la vue.
Tamilarasi
4

Vous pouvez utiliser le plugin jQuery scrollTo plugin:

$('div').scrollTo('#row_8');
nickf
la source
1
le lien n'est plus disponible. pourriez-vous le mettre à jour.?
Lucky
2

Faire défiler l'élément jusqu'au centre du conteneur

Amener l'élément au centre du conteneur.

DEMO sur CODEPEN

JS

function scrollToCenter() {
  var container = $('.container'),
    scrollTo = $('.5');

  container.animate({
    //scrolls to center
    scrollTop: scrollTo.offset().top - container.offset().top + scrollTo.scrollTop() - container.height() / 2
  });
}

HTML

<div class="container">
   <div class="1">
    1
  </div>
  <div class="2">
    2
  </div>
  <div class="3">
    3
  </div>
  <div class="4">
    4
  </div>
  <div class="5">
    5
  </div>
  <div class="6">
    6
  </div>
  <div class="7">
    7
  </div>
  <div class="8">
    8
  </div>
  <div class="9">
    9
  </div>
  <div class="10">
    10
  </div>


</div>
<br>
<br>
<button id="scroll" onclick="scrollToCenter()">
  Scroll
</button>

css

.container {
  height: 60px;
  overflow-y: scroll;
  width 60px;
  background-color: white;
}

Il n'est pas exact au centre mais vous ne le reconnaîtrez pas sur des éléments plus grands et plus grands.

basti500
la source
2

Vous pouvez faire défiler par jQuery et JavaScript Juste besoin de deux éléments jQuery et ce code JavaScript:

$(function() {
  // Generic selector to be used anywhere
  $(".js-scroll-to-id").click(function(e) {

    // Get the href dynamically
    var destination = $(this).attr('href');

    // Prevent href=“#” link from changing the URL hash (optional)
    e.preventDefault();

    // Animate scroll to destination
    $('html, body').animate({
      scrollTop: $(destination).offset().top
    }, 1500);
  });
});

MD Ashik
la source
1

J'ai fait une combinaison de ce que d'autres ont posté. C'est simple et lisse

 $('#myButton').click(function(){
        $('html, body').animate({
            scrollTop: $('#scroll-to-this-element').position().top },
            1000
        );
    });
Nlinscott
la source
@ AnriëtteMyburgh je ne sais pas si position () est fonctionnel sur tous les navigateurs. L'avez-vous essayé dans d'autres pour voir si cela fonctionne? Ou puis-je voir le code que vous utilisez et voir s'il y a quelque chose d'autre qui ne va pas?
Nlinscott
1

Je ne sais pas pourquoi personne ne dit l'évidence, car il existe une scrollTofonction javascript intégrée:

scrollTo( $('#element').position().top );

Référence .

Kevin
la source
6
scrollTo nécessite deux arguments, vous n'en avez écrit qu'un.
NuclearPeon
2
... et il est appelé sur l'objet fenêtre.
hashchange
1

Contrairement à ce que la plupart des gens ici sont ce qui suggère, je vous recommande de faire utiliser un plug - in si vous voulez animer le mouvement. Il ne suffit pas d'animer scrollTop pour une expérience utilisateur fluide. Voir ma réponse ici pour le raisonnement.

J'ai essayé un certain nombre de plugins au fil des ans, mais j'ai fini par en écrire un moi-même. Vous voudrez peut-être lui donner un spin: jQuery.scrollable . En utilisant cela, l'action de défilement devient

$container.scrollTo( targetPosition );

Mais ce n'est pas tout. Nous devons également fixer la position cible. Le calcul que vous voyez dans d'autres réponses,

$target.offset().top - $container.offset().top + $container.scrollTop()

fonctionne principalement mais n'est pas entièrement correct. Il ne gère pas correctement la bordure du conteneur de défilement. L'élément cible est défilé trop haut, de la taille de la bordure. Voici une démo.

Par conséquent, une meilleure façon de calculer la position cible est

var target = $target[0], 
    container = $container[0];

targetPosition = $container.scrollTop() + target.getBoundingClientRect().top - container.getBoundingClientRect().top - container.clientTop;

Encore une fois, regardez la démo pour la voir en action.

Pour une fonction qui renvoie la position cible et fonctionne à la fois pour les conteneurs de défilement fenêtre et non-fenêtre, n'hésitez pas à utiliser cet élément essentiel . Les commentaires qui y figurent expliquent comment la position est calculée.

Au début, j'ai dit qu'il serait préférable d'utiliser un plugin pour le défilement animé . Vous n'avez cependant pas besoin d'un plugin si vous souhaitez accéder à la cible sans transition. Voir la réponse de @James pour cela, mais assurez-vous de calculer correctement la position cible s'il y a une bordure autour du conteneur.

hashchange
la source
0

Pour ce que ça vaut, c'est comme ça que j'ai réussi à réaliser un tel comportement pour un élément général qui peut être à l'intérieur d'un DIV avec défilement (sans connaître le container)

Il crée une fausse entrée de la hauteur de l'élément cible, puis y met l'accent, et le navigateur se charge du reste, quelle que soit la profondeur de la hiérarchie déroulante. Fonctionne comme un charme.

var $scrollTo = $('#someId'),
inputElem = $('<input type="text"></input>');

$scrollTo.prepend(inputElem);
inputElem.css({
  position: 'absolute',
  width: '1px',
  height: $scrollTo.height()
});
inputElem.focus();
inputElem.remove();
martinh_kentico
la source
0

J'ai fait cette combinaison. son travail pour moi. mais face à un problème si le clic clique sur cette taille de div est trop grande pour que scenerio défile pas vers le bas pour cette div particulière.

 var scrollDownTo =$("#show_question_" + nQueId).position().top;
        console.log(scrollDownTo);
        $('#slider_light_box_container').animate({
            scrollTop: scrollDownTo
            }, 1000, function(){
        });

        }
scode2704
la source