web-dev-qa-db-fra.com

Comment faire défiler un élément avec jQuery?

J'ai un document HTML avec des images dans un format de grille utilisant <ul><li><img.... La fenêtre du navigateur présente un défilement vertical et horizontal. 

Question: Lorsque je clique sur une image <img>, comment puis-je faire en sorte que tout le document défile jusqu'à une position où l'image sur laquelle je viens de cliquer est top:20px; left:20px?

J'ai parcouru ici des articles similaires ... bien que je sois assez novice en JavaScript et que je veuille comprendre comment cela s'est réalisé.

136
Nasir

Puisque vous voulez savoir comment cela fonctionne, je vais vous l'expliquer étape par étape.

Tout d'abord, vous souhaitez lier une fonction en tant que gestionnaire de clic de l'image:

$('#someImage').click(function () {
    // Code to do scrolling happens here
});

Cela va appliquer le gestionnaire de clics à une image avec id="someImage". Si vous voulez utiliser ceci pour all images, remplacez '#someImage' par 'img'.

Passons maintenant au code de défilement actuel:

  1. Obtenir les décalages d'image (par rapport au document):

    var offset = $(this).offset(); // Contains .top and .left
    
  2. Soustrayez 20 de top et left:

    offset.left -= 20;
    offset.top -= 20;
    
  3. Maintenant, animez les propriétés CSS scroll-top et scroll-left de <body> et <html>:

    $('html, body').animate({
        scrollTop: offset.top,
        scrollLeft: offset.left
    });
    
175
David Tang

Il existe une méthode DOM appelée scrollIntoView , prise en charge par tous les principaux navigateurs, qui aligne un élément sur le haut/gauche de la fenêtre (ou aussi proche que possible).

$("#myImage")[0].scrollIntoView();

Sur les navigateurs pris en charge, vous pouvez fournir des options:

$("#myImage")[0].scrollIntoView({
    behavior: "smooth", // or "auto" or "instant"
    block: "start" // or "end"
});

Si tous les éléments ont des ID uniques, vous pouvez également modifier la propriété hash de l'objet location / pour la prise en charge du bouton Précédent/Suivant:

$(document).delegate("img", function (e) {
    if (e.target.id)
        window.location.hash = e.target.id;
});

Après cela, ajustez simplement les propriétés scrollTop/scrollLeft de -20:

document.body.scrollLeft -= 20;
document.body.scrollTop -= 20;
321
Andy E

La solution la plus simple que j'ai vue

$('html, body').animate({
    scrollTop: $("#target-element").offset().top
}, 1000);

Tutorial Here

7
Matt Watson

Jetez un coup d'œil au jQuery.scrollTo plugin. Voici un demo .

Ce plugin a beaucoup d’options qui vont au-delà de ce que native scrollIntoView vous offre. Par exemple, vous pouvez définir le défilement comme étant fluide, puis définir un rappel pour la fin du défilement.

Vous pouvez également consulter tous les plug-ins JQuery marqués avec "scroll" .

7

Il existe des méthodes pour faire défiler un élément directement dans la vue, mais si vous souhaitez faire défiler un point relatif à partir d'un élément, vous devez le faire manuellement:

Dans le gestionnaire de clics, obtenez la position de l'élément par rapport au document, soustrayez 20 et utilisez window.scrollTo :

var pos = $(this).offset();
var top = pos.top - 20;
var left = pos.left - 20;
window.scrollTo((left < 0 ? 0 : left), (top < 0 ? 0 : top));
7
Felix Kling

Voici un plugin rapide jQuery pour bien cartographier les fonctionnalités du navigateur

$.fn.ensureVisible = function () { $(this).each(function () { $(this)[0].scrollIntoView(); }); };

...

$('.my-elements').ensureVisible();
4
Rob

Juste un pourboire. Fonctionne sur Firefox uniquement

Element.scrollIntoView ();

3
wp student

Après essais et erreurs, je suis arrivé à cette fonction, fonctionne aussi avec iframe.

function bringElIntoView(el) {    
    var elOffset = el.offset();
    var $window = $(window);
    var windowScrollBottom = $window.scrollTop() + $window.height();
    var scrollToPos = -1;
    if (elOffset.top < $window.scrollTop()) // element is hidden in the top
        scrollToPos = elOffset.top;
    else if (elOffset.top + el.height() > windowScrollBottom) // element is hidden in the bottom
        scrollToPos = $window.scrollTop() + (elOffset.top + el.height() - windowScrollBottom);
    if (scrollToPos !== -1)
        $('html, body').animate({ scrollTop: scrollToPos });
}
2
Tone Škoda

Mon interface utilisateur comporte une liste déroulante verticale de pouces dans une barre de pouce Le but était de placer le pouce actuel au centre de la barre de pouce . Je suis parti de la réponse approuvée, mais j'ai constaté quelques modifications à vraiment centrer le pouce actuel. J'espère que ceci aide quelqu'un d'autre.

balisage:

<ul id='thumbbar'>
    <li id='thumbbar-123'></li>
    <li id='thumbbar-124'></li>
    <li id='thumbbar-125'></li>
</ul>

jquery:

// scroll the current thumb bar thumb into view
heightbar   = $('#thumbbar').height();
heightthumb = $('#thumbbar-' + pageid).height();
offsetbar   = $('#thumbbar').scrollTop();


$('#thumbbar').animate({
    scrollTop: offsetthumb.top - heightbar / 2 - offsetbar - 20
});
1
xeo

Simple 2 étapes pour faire défiler vers le bas ou la fin. 

Étape 1: obtenez toute la hauteur de div.

Étape 2: appliquez scrollTop sur cette division (conversation) défilable en utilisant la valeur. obtenu à l'étape1.

var fullHeight = $('#conversation')[0].scrollHeight;

$('#conversation').scrollTop(fullHeight);

Les étapes ci-dessus doivent être appliquées pour chaque ajout à la conversation.

0
Shiva Kumar P

Après avoir essayé de trouver une solution qui tienne compte de toutes les circonstances (options pour animer le défilement, parcourir l’objet une fois défilé, fonctionne même dans des circonstances obscures, comme dans un iframe), j’ai finalement écrit ma propre solution. Comme cela semble fonctionner alors que de nombreuses autres solutions ont échoué, j'ai pensé le partager:

function scrollIntoViewIfNeeded($target, options) {

    var options = options ? options : {},
    $win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
    $container = options.$container ? options.$container : $win,        
    padding = options.padding ? options.padding : 20,
    elemTop = $target.offset().top,
    elemHeight = $target.outerHeight(),
    containerTop = $container.scrollTop(),
    //Everything past this point is used only to get the container's visible height, which is needed to do this accurately
    containerHeight = $container.outerHeight(),
    winTop = $win.scrollTop(),
    winBot = winTop + $win.height(),
    containerVisibleTop = containerTop < winTop ? winTop : containerTop,
    containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
    containerVisibleHeight = containerVisibleBottom - containerVisibleTop;

    if (elemTop < containerTop) {
        //scroll up
        if (options.instant) {
            $container.scrollTop(elemTop - padding);
        } else {
            $container.animate({scrollTop: elemTop - padding}, options.animationOptions);
        }
    } else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
        //scroll down
        if (options.instant) {
            $container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
        } else {
            $container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
        }
    }
}

$target est un objet jQuery contenant l'objet que vous souhaitez faire défiler dans l'affichage si nécessaire.

options (facultatif) peut contenir les options suivantes passées dans un objet:

options.$container - un objet jQuery pointant sur l'élément contenant de $ target (autrement dit, l'élément du dom avec les barres de défilement). Par défaut, la fenêtre contenant l'élément $ target est suffisamment intelligente pour sélectionner une fenêtre iframe. N'oubliez pas d'inclure le $ dans le nom de la propriété.

options.padding - le remplissage en pixels à ajouter au-dessus ou au-dessous de l'objet lorsqu'il défile dans l'affichage. De cette façon, ce n'est pas juste contre le bord de la fenêtre. La valeur par défaut est 20.

options.instant - s'il est défini sur true, jQuery animate ne sera pas utilisé et le défilement apparaîtra instantanément au bon emplacement. La valeur par défaut est false.

options.animationOptions - toute option jQuery que vous souhaitez transmettre à la fonction d'animation jQuery (voir http://api.jquery.com/animate/ ). Avec cela, vous pouvez changer la durée de l'animation ou faire exécuter une fonction de rappel une fois le défilement terminé. Cela ne fonctionne que si options.instant est défini sur false. Si vous avez besoin d'une animation instantanée mais avec un rappel, définissez options.animationOptions.duration = 0 au lieu d'utiliser options.instant = true.

0
dallin