Je crée un système de pagination (un peu comme Facebook) où le contenu est chargé lorsque l'utilisateur fait défiler l'écran vers le bas. J'imagine que la meilleure façon de le faire est de savoir quand l'utilisateur est au bas de la page et d'exécuter une requête ajax pour charger plus de messages.
Le seul problème est que je ne sais pas comment vérifier si l'utilisateur a fait défiler la page au bas de la page avec jQuery. Des idées?
Je dois trouver un moyen de vérifier si l'utilisateur a fait défiler le bas de la page avec jQuery.
Utilisez le .scroll()
event sur window
, comme ceci:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
alert("bottom!");
}
});
Vous pouvez le tester ici , cela prend le défilement supérieur de la fenêtre, donc combien de fois il fait défiler, ajoute la hauteur de la fenêtre visible et vérifie si cela est égal à la hauteur du contenu global (document
). Si vous vouliez plutôt vérifier si l'utilisateur est près de en bas, cela ressemblerait à ceci:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
alert("near bottom!");
}
});
Vous pouvez tester cette version ici , ajustez simplement ce 100
en fonction du pixel à partir du bas sur lequel vous souhaitez déclencher.
La réponse de Nick Craver fonctionne bien, évitez le fait que la valeur de $(document).height()
varie selon le navigateur.
Pour que cela fonctionne sur tous les navigateurs, utilisez cette fonction de James Padolsey :
function getDocHeight() {
var D = document;
return Math.max(
D.body.scrollHeight, D.documentElement.scrollHeight,
D.body.offsetHeight, D.documentElement.offsetHeight,
D.body.clientHeight, D.documentElement.clientHeight
);
}
à la place de $(document).height()
, de sorte que le code final est:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == getDocHeight()) {
alert("bottom!");
}
});
Je ne sais pas exactement pourquoi cela n'a pas encore été publié, mais selon la documentation de MDN , le moyen le plus simple consiste à utiliser des propriétés javascript natives:
element.scrollHeight - element.scrollTop === element.clientHeight
Renvoie true lorsque vous êtes au bas d'un élément défilable. Si simplement en utilisant javascript:
element.addEventListener('scroll', function(event)
{
var element = event.target;
if (element.scrollHeight - element.scrollTop === element.clientHeight)
{
console.log('scrolled');
}
});
scrollHeight
supporte largement les navigateurs, de 8 à plus précis, alors que clientHeight
et scrollTop
sont tous les deux supportés par tout le monde. Même c'est-à-dire 6. Cela devrait être sécurisé entre navigateurs.
Pour ceux qui utilisent la solution de Nick et reçoivent des alertes/événements répétés, vous pouvez ajouter une ligne de code au-dessus de l'exemple d'alerte:
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$(window).unbind('scroll');
alert("near bottom!");
}
});
Cela signifie que le code ne sera déclenché que la première fois que vous vous trouvez à moins de 100 pixels du bas du document. Cela ne se répètera pas si vous faites défiler vers le haut, puis le bas, ce qui peut être utile ou non, en fonction de l'utilisation du code de Nick.
En plus de l’excellente réponse acceptée par Nick Craver, vous pouvez limiter l’événement de défilement afin qu’il ne soit pas déclenché aussi souvent, ainsi augmentant les performances du navigateur:
var _throttleTimer = null;
var _throttleDelay = 100;
var $window = $(window);
var $document = $(document);
$document.ready(function () {
$window
.off('scroll', ScrollHandler)
.on('scroll', ScrollHandler);
});
function ScrollHandler(e) {
//throttle event:
clearTimeout(_throttleTimer);
_throttleTimer = setTimeout(function () {
console.log('scroll');
//do work
if ($window.scrollTop() + $window.height() > $document.height() - 100) {
alert("near bottom!");
}
}, _throttleDelay);
}
La réponse de Nick Craver doit être légèrement modifiée pour fonctionner sur iOS 6 Safari Mobile et devrait être:
$(window).scroll(function() {
if($(window).scrollTop() + window.innerHeight == $(document).height()) {
alert("bottom!");
}
});
La modification de $ (window) .height () en window.innerHeight doit être effectuée car lorsque la barre d'adresse est masquée, 60 pixels supplémentaires sont ajoutés au La hauteur de la fenêtre, mais l'utilisation de $(window).height()
ne reflète pas reflète ce changement, alors que l'utilisation de window.innerHeight
l'est.
Note: la propriété window.innerHeight
inclut également la hauteur de la barre de défilement horizontale (si elle est rendue), contrairement à $(window).height()
qui n'inclut pas la hauteur de la barre de défilement horizontale. Ce n'est pas un problème dans Mobile Safari, mais cela peut entraîner un comportement inattendu sur les autres navigateurs ou les futures versions de Mobile Safari. Remplacer ==
par >=
pourrait résoudre ce problème dans les cas d'utilisation les plus courants.
En savoir plus sur la propriété window.innerHeight
ici
Voici une approche assez simple:
Elm.onscroll = function() {
if(Elm.scrollTop + Elm.clientHeight == Elm.scrollHeight) //User has scrolled to the bottom of the element
}
Voici un morceau de code qui vous aidera à déboguer votre code. J'ai testé les réponses ci-dessus et je les ai trouvées boguées. J'ai tester les suivants sur Chrome, IE, Firefox, IPad (Safari). Je n'ai pas d'autres installés pour tester ...
<script type="text/javascript">
$(function() {
$(window).scroll(function () {
var docElement = $(document)[0].documentElement;
var winElement = $(window)[0];
if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
alert('bottom');
}
});
});
</script>
Il y a peut-être une solution plus simple, mais je me suis arrêté au point où IT WORKED
Si vous rencontrez toujours des problèmes avec un navigateur non autorisé, voici du code pour vous aider à déboguer:
<script type="text/javascript">
$(function() {
$(window).scroll(function () {
var docElement = $(document)[0].documentElement;
var details = "";
details += '<b>Document</b><br />';
details += 'clientHeight:' + docElement.clientHeight + '<br />';
details += 'clientTop:' + docElement.clientTop + '<br />';
details += 'offsetHeight:' + docElement.offsetHeight + '<br />';
details += 'offsetParent:' + (docElement.offsetParent == null) + '<br />';
details += 'scrollHeight:' + docElement.scrollHeight + '<br />';
details += 'scrollTop:' + docElement.scrollTop + '<br />';
var winElement = $(window)[0];
details += '<b>Window</b><br />';
details += 'innerHeight:' + winElement.innerHeight + '<br />';
details += 'outerHeight:' + winElement.outerHeight + '<br />';
details += 'pageYOffset:' + winElement.pageYOffset + '<br />';
details += 'screenTop:' + winElement.screenTop + '<br />';
details += 'screenY:' + winElement.screenY + '<br />';
details += 'scrollY:' + winElement.scrollY + '<br />';
details += '<b>End of page</b><br />';
details += 'Test:' + (docElement.scrollHeight - winElement.innerHeight) + '=' + winElement.pageYOffset + '<br />';
details += 'End of Page? ';
if ((docElement.scrollHeight - winElement.innerHeight) == winElement.pageYOffset) {
details += 'YES';
} else {
details += 'NO';
}
$('#test').html(details);
});
});
</script>
<div id="test" style="position: fixed; left:0; top: 0; z-index: 9999; background-color: #FFFFFF;">
J'espère que cela sauvera du temps à quelqu'un.
var elemScrolPosition = elem.scrollHeight - elem.scrollTop - elem.clientHeight;
Il calcule la barre de défilement de la distance jusqu'au bas de l'élément . Égal à 0, si la barre de défilement a atteint le bas
S'il vous plaît vérifier cette réponse
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log("bottom");
}
};
Vous pouvez faire footerHeight - document.body.offsetHeight
pour voir si vous êtes près du pied de page ou si vous avez atteint le pied de page.
Ce sont mes deux centimes:
$('#container_element').scroll( function(){
console.log($(this).scrollTop()+' + '+ $(this).height()+' = '+ ($(this).scrollTop() + $(this).height()) +' _ '+ $(this)[0].scrollHeight );
if($(this).scrollTop() + $(this).height() == $(this)[0].scrollHeight){
console.log('bottom found');
}
});
Pure JS avec cross-browser et debouncing _ (Assez bon performance)
var CheckIfScrollBottom = debouncer(function() {
if(getDocHeight() == getScrollXY()[1] + window.innerHeight) {
console.log('Bottom!');
}
},500);
document.addEventListener('scroll',CheckIfScrollBottom);
function debouncer(a,b,c){var d;return function(){var e=this,f=arguments,g=function(){d=null,c||a.apply(e,f)},h=c&&!d;clearTimeout(d),d=setTimeout(g,b),h&&a.apply(e,f)}}
function getScrollXY(){var a=0,b=0;return"number"==typeof window.pageYOffset?(b=window.pageYOffset,a=window.pageXOffset):document.body&&(document.body.scrollLeft||document.body.scrollTop)?(b=document.body.scrollTop,a=document.body.scrollLeft):document.documentElement&&(document.documentElement.scrollLeft||document.documentElement.scrollTop)&&(b=document.documentElement.scrollTop,a=document.documentElement.scrollLeft),[a,b]}
function getDocHeight(){var a=document;return Math.max(a.body.scrollHeight,a.documentElement.scrollHeight,a.body.offsetHeight,a.documentElement.offsetHeight,a.body.clientHeight,a.documentElement.clientHeight)}
Démo:http://jsbin.com/geherovena/edit?js,output
_ {PS: Debouncer
, getScrollXY
, getDocHeight
non écrit par moi} _
_ {Je viens de montrer comment ça marche, et comment je vais faire} _
Vous pouvez essayer le code suivant,
$("#dashboard-scroll").scroll(function(){
var ele = document.getElementById('dashboard-scroll');
if(ele.scrollHeight - ele.scrollTop === ele.clientHeight){
console.log('at the bottom of the scroll');
}
});
Nick répond bien, mais vous aurez des fonctions qui se répètent lors du défilement ou qui ne fonctionneront pas du tout si la fenêtre est zoomée. Je suis venu avec une solution facile juste math.round la première hauteur et cela fonctionne comme supposé.
if (Math.round($(window).scrollTop()) + $(window).innerHeight() == $(document).height()){
loadPagination();
$(".go-up").css("display","block").show("slow");
}
Essayez ceci pour la condition de correspondance si faites défiler vers le bas
if ($(this)[0].scrollHeight - $(this).scrollTop() ==
$(this).outerHeight()) {
//code for your custom logic
}
Toutes ces solutions ne fonctionnent pas pour moi sous Firefox et Chrome, j'utilise donc les fonctions personnalisées de Miles O'Keefe et meder omuraliev comme ceci:
function getDocHeight()
{
var D = document;
return Math.max(
D.body.scrollHeight, D.documentElement.scrollHeight,
D.body.offsetHeight, D.documentElement.offsetHeight,
D.body.clientHeight, D.documentElement.clientHeight
);
}
function getWindowSize()
{
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
return [myWidth, myHeight];
}
$(window).scroll(function()
{
if($(window).scrollTop() + getWindowSize()[1] == getDocHeight())
{
alert("bottom!");
}
});
Laissez-moi montrer l'approche sans JQuery. Fonction JS simple:
function isVisible(elem) {
var coords = elem.getBoundingClientRect();
var topVisible = coords.top > 0 && coords.top < 0;
var bottomVisible = coords.bottom < shift && coords.bottom > 0;
return topVisible || bottomVisible;
}
Petit exemple comment l'utiliser:
var img = document.getElementById("pic1");
if (isVisible(img)) { img.style.opacity = "1.00"; }
Cela donne des résultats précis, lorsqu’il vérifie un élément défilant (c’est-à-dire pas window
):
// `element` is a native JS HTMLElement
if ( element.scrollTop == (element.scrollHeight - element.offsetHeight) )
// Element scrolled to bottom
offsetHeight
doit donner la réelle visible hauteur d'un élément (y compris les barres de défilement, la marge, et), et scrollHeight
est la hauteur entière d'un élément, y compris les zones invisibles (débordées).
jQuery
's .outerHeight()
devrait donner un résultat similaire à celui de JS .offsetHeight
-- La documentation dans MDN pour offsetHeight
ne permet pas de déterminer avec précision sa prise en charge multi-navigateurs. Pour couvrir plus d'options, ceci est plus complet:
var offsetHeight = ( container.offsetHeight ? container.offsetHeight : $(container).outerHeight() );
if ( container.scrollTop == (container.scrollHeight - offsetHeight) ) {
// scrolled to bottom
}
Pour arrêter l'alerte répétée de la réponse de Nick
ScrollActivate();
function ScrollActivate() {
$(window).on("scroll", function () {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$(window).off("scroll");
alert("near bottom!");
}
});
}
Google Chrome donne toute la hauteur de la page si vous appelez $(window).height()
À la place, utilisez window.innerHeight
pour récupérer la hauteur de votre fenêtre. Le chèque nécessaire devrait être:
if($(window).scrollTop() + window.innerHeight > $(document).height() - 50) {
console.log("reached bottom!");
}
J'ai utilisé @ddanone answear et ajouté Ajax call.
$('#mydiv').on('scroll', function(){
function infiniScroll(this);
});
function infiniScroll(mydiv){
console.log($(mydiv).scrollTop()+' + '+ $(mydiv).height()+' = '+ ($(mydiv).scrollTop() + $(mydiv).height()) +' _ '+ $(mydiv)[0].scrollHeight );
if($(mydiv).scrollTop() + $(mydiv).height() == $(mydiv)[0].scrollHeight){
console.log('bottom found');
if(!$.active){ //if there is no ajax call active ( last ajax call waiting for results ) do again my ajax call
myAjaxCall();
}
}
}
Ma solution en clair js:
let el=document.getElementById('el');
el.addEventListener('scroll', function (e) {
if (el.scrollHeight - el.scrollTop - el.clientHeight<0) {
console.log('Bottom')
}
});
#el{
width:300px;
height:100px;
overflow-y:scroll;
}
<div id="el">
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
<div>content</div>
</div>
Voici mes deux cents comme la réponse acceptée ne m'a pas fonctionné.
var documentAtBottom = (document.documentElement.scrollTop + window.innerHeight) >= document.documentElement.scrollHeight;