J'ai besoin de récupérer la hauteur visible d'un div dans une zone de défilement. Je me considère assez décent avec jQuery, mais cela me dérange complètement.
Disons que j'ai un div rouge dans un emballage noir:
Dans le graphique ci-dessus, la fonction jQuery renverrait 248, la partie visible du div.
Une fois que l'utilisateur fait défiler le haut du div, comme dans le graphique ci-dessus, il signale 296.
Maintenant, une fois que l'utilisateur a fait défiler le div, il signale à nouveau 248.
Évidemment, mes chiffres ne seront pas aussi cohérents et clairs que dans cette démo, ou je coderais simplement ces chiffres en dur.
J'ai un peu une théorie:
- Obtenez la hauteur de la fenêtre
- Obtenez la hauteur de la div
- Obtenez le décalage initial du div à partir du haut de la fenêtre
- Obtenez le décalage lorsque l'utilisateur fait défiler.
- Si le décalage est positif, cela signifie que le haut du div est toujours visible.
- s'il est négatif, le haut du div a été éclipsé par la fenêtre. À ce stade, le div pourrait occuper toute la hauteur de la fenêtre ou le bas du div pourrait afficher
- Si le bas du div s'affiche, déterminez l'écart entre celui-ci et le bas de la fenêtre.
Cela semble assez simple, mais je ne peux tout simplement pas comprendre. Je vais prendre une autre fissure demain matin; J'ai juste pensé que certains d'entre vous, les génies, pourraient peut-être aider.
Merci!
MISE À JOUR: J'ai compris cela par moi-même, mais il semble que l'une des réponses ci-dessous soit plus élégante, donc je vais l'utiliser à la place. Pour les curieux, voici ce que j'ai trouvé:
$(document).ready(function() {
var windowHeight = $(window).height();
var overviewHeight = $("#overview").height();
var overviewStaticTop = $("#overview").offset().top;
var overviewScrollTop = overviewStaticTop - $(window).scrollTop();
var overviewStaticBottom = overviewStaticTop + $("#overview").height();
var overviewScrollBottom = windowHeight - (overviewStaticBottom - $(window).scrollTop());
var visibleArea;
if ((overviewHeight + overviewScrollTop) < windowHeight) {
// alert("bottom is showing!");
visibleArea = windowHeight - overviewScrollBottom;
// alert(visibleArea);
} else {
if (overviewScrollTop < 0) {
// alert("is full height");
visibleArea = windowHeight;
// alert(visibleArea);
} else {
// alert("top is showing");
visibleArea = windowHeight - overviewScrollTop;
// alert(visibleArea);
}
}
});
la source
Réponses:
Voici un concept rapide et sale. Il compare fondamentalement le
offset().top
de l'élément au haut de la fenêtre et leoffset().top + height()
au bas de la fenêtre:function getVisible() { var $el = $('#foo'), scrollTop = $(this).scrollTop(), scrollBot = scrollTop + $(this).height(), elTop = $el.offset().top, elBottom = elTop + $el.outerHeight(), visibleTop = elTop < scrollTop ? scrollTop : elTop, visibleBottom = elBottom > scrollBot ? scrollBot : elBottom; $('#notification').text(visibleBottom - visibleTop); } $(window).on('scroll resize', getVisible);
Exemple de violon
edit - petite mise à jour pour exécuter également la logique lorsque la fenêtre est redimensionnée.
la source
div
s sans simplement répéter le code. Y a-t-il un moyen de faire cela?Calculer la quantité de px d'un élément (hauteur) dans la fenêtre
Démo Fiddle
Cette petite fonction renverra la quantité d'
px
un élément visible dans la fenêtre (verticale) :function inViewport($el) { var elH = $el.outerHeight(), H = $(window).height(), r = $el[0].getBoundingClientRect(), t=r.top, b=r.bottom; return Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H)); }
Utilisez comme:
$(window).on("scroll resize", function(){ console.log( inViewport($('#elementID')) ); // n px in viewport });
c'est ça.
.inViewport()
Plugin jQueryDémo jsFiddle
à partir de ce qui précède, vous pouvez extraire la logique et créer un plugin comme celui-ci:
/** * inViewport jQuery plugin by Roko C.B. * http://stackoverflow.com/a/26831113/383904 * Returns a callback function with an argument holding * the current amount of px an element is visible in viewport * (The min returned value is 0 (element outside of viewport) */ ;(function($, win) { $.fn.inViewport = function(cb) { return this.each(function(i,el) { function visPx(){ var elH = $(el).outerHeight(), H = $(win).height(), r = el.getBoundingClientRect(), t=r.top, b=r.bottom; return cb.call(el, Math.max(0, t>0? Math.min(elH, H-t) : Math.min(b, H))); } visPx(); $(win).on("resize scroll", visPx); }); }; }(jQuery, window));
Utilisez comme:
$("selector").inViewport(function(px) { console.log( px ); // `px` represents the amount of visible height if(px > 0) { // do this if element enters the viewport // px > 0 }else{ // do that if element exits the viewport // px = 0 } }); // Here you can chain other jQuery methods to your selector
vos sélecteurs écouteront dynamiquement la fenêtre
scroll
etresize
renverront également la valeur initiale sur le DOM prêt via le premier argument de la fonction de rappelpx
.la source
<meta name="viewport" content="width=your_size">
dans la section html principale.content="width=1259"
cela convienne à la majorité. Avez-vous essayé à lacontent="width=device-width, initial-scale=1"
place?<meta name="viewport" content="your_content">
déclaration :)visible height px
, comme un objet. Voir ce violon pour une telle idée: jsfiddle.net/RokoCB/6xjq5gyy (ouvrir la console du développeur pour voir les journaux)Voici une version de l'approche de Rory ci-dessus, sauf écrite pour fonctionner comme un plugin jQuery. Il peut avoir une applicabilité plus générale dans ce format. Excellente réponse, Rory - merci!
$.fn.visibleHeight = function() { var elBottom, elTop, scrollBot, scrollTop, visibleBottom, visibleTop; scrollTop = $(window).scrollTop(); scrollBot = scrollTop + $(window).height(); elTop = this.offset().top; elBottom = elTop + this.outerHeight(); visibleTop = elTop < scrollTop ? scrollTop : elTop; visibleBottom = elBottom > scrollBot ? scrollBot : elBottom; return visibleBottom - visibleTop }
Peut être appelé avec les éléments suivants:
$("#myDiv").visibleHeight();
jsFiddle
la source