si vous essayez d'obtenir un décalage supérieur à partir d'un élément de la liste dans un parent et que ce parent n'est pas placé en haut, vous obtiendrez une valeur erronée.
http://jsbin.com/yuxacuduna/1/edit?html,css,js,console,output
Essayez de supprimer le margin-top
sur l'élément .container
et vous verrez qu'il fonctionnera.
Quelle est la solution à ce problème?
Ta question:
Quelle est la solution à ce problème?
Je vous suggère de positionner le .container
à relative
:
.container{
margin-top:100px;
background:yellow;
height:600px;
width:300px;
overflow-y:auto;
overflow-x:hidden;
position:relative; /*<---add this*/
}
et dans votre script, utilisez .position().top
, cela vous facilitera la vie:
$('.container li:nth-child(7)').css("background", "red");
$('.container').animate({
scrollTop: $('.container li:nth-child(7)').position().top
});
.offset().top
:
Description: Obtenir les coordonnées actuelles du premier élément de l'ensemble des éléments correspondants, relatives au document.
.position().top
:
À partir de la documentation:
Description:Obtenir les coordonnées actuelles du premier élément de l'ensemble des éléments correspondants, par rapport au parent décalé.
.position().top
est calculé du haut vers le parent si parent est relativement positionné.
$(function() {
$('.container li:nth-child(7)').css("background", "red");
$('.container').animate({
scrollTop: $('.container li:nth-child(7)').position().top
});
});
html,
body {
margin: 0;
padding: 0;
}
.container {
margin-top: 100px;
background: yellow;
height: 600px;
width: 300px;
overflow-y: auto;
overflow-x: hidden;
position: relative;
}
.container ul {
margin: 0;
padding: 0;
list-style: none outside none;
}
.container li {
background: blue;
display: block;
height: 150px;
width: 100%;
padding: 10px;
margin-bottom: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<ul>
<li>asdasd</li>
<li>asdasd</li>
<li>asdasd</li>
<li>asdasd</li>
<li>asdasd</li>
<li>asdasd</li>
<li>asdasd77</li>
<li>asdasd</li>
<li>asdasd</li>
<li>asdasd</li>
<li>asdasd</li>
</ul>
</div>
Vous pouvez également rencontrer ce problème si une partie de votre contenu est constituée d'images. Si vous appelez .offset () dans document.ready (), les images ne sont peut-être pas encore chargées. Essayez de déplacer votre appel .offset () vers window.load ().
Je pense que ça fonctionne correctement. Selon offset()
documentation jQuery :
La méthode .offset () nous permet de récupérer la position actuelle d'un élément relatif au document
Donc, le problème que vous avez est que vous essayez de faire défiler la ul
mais avec la valeur du scrollTop de l'élément dans le document, et non dans la liste. Pour résoudre ce problème, corrigez simplement la valeur en prenant en compte le scrollTop du parent (le ul
):
$(function(){
$('.container li:nth-child(7)').css("background", "red");
$('.container').animate({
scrollTop: $('.container li:nth-child(7)').offset().top - $(".container").offset().top
});
});
Vous pouvez le voir travailler sur cette modification de votre JSBin: http://jsbin.com/fanixodiwi/1/edit?html,css,js,console,output }
J'ai eu le même problème. Toutes les solutions sur le Web ne fonctionnent pas pour moi.
Si vous utilisez margin pour séparer certains éléments sans bordure, utilisez plutôt un remplissage. La fonction offset () de jQuery comptera pour les rembourrages mais exclura les marges. Les numéros de position en offset () redeviendront corrects.