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é.
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:
Obtenir les décalages d'image (par rapport au document):
var offset = $(this).offset(); // Contains .top and .left
Soustrayez 20 de top
et left
:
offset.left -= 20;
offset.top -= 20;
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
});
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;
La solution la plus simple que j'ai vue
$('html, body').animate({
scrollTop: $("#target-element").offset().top
}, 1000);
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" .
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));
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();
Juste un pourboire. Fonctionne sur Firefox uniquement
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 });
}
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
});
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.
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
.