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 rejette 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 de la div.
Une fois que l'utilisateur a dépassé le haut de la div, comme indiqué dans le graphique ci-dessus, il enregistre 296.
Maintenant, une fois que l'utilisateur a fait défiler le div, il en signalera à nouveau 248.
De toute évidence, mes chiffres ne seront pas aussi cohérents et clairs que dans cette démo, sinon je coderais simplement pour ces chiffres.
J'ai un peu de théorie:
Cela semble assez simple, mais je ne peux tout simplement pas comprendre. Je vais prendre une autre fissure demain matin; Je pensais que certains de vos génies pourraient peut-être vous aider.
Merci!
MISE À JOUR: J'ai découvert cela par moi-même, mais il semblerait qu'une des réponses ci-dessous soit plus élégante. Je vais donc l'utiliser à la place. Pour les curieux, voici ce que j'ai inventé:
$(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);
}
}
});
Voici un concept rapide et sale. Il compare fondamentalement la offset().top
de l'élément au haut de la fenêtre et la offset().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);
edit - petite mise à jour pour exécuter également la logique lorsque la fenêtre est redimensionnée.
Cette petite fonction renverra le montant de px
un élément est visible dans la (verticale) Viewport =:
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 tout.
.inViewport()
pluginà 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
et resize
, mais renverront également la valeur initiale sur DOM ready par le premier argument de la fonction de rappel px
.
Voici une version de l'approche de Rory ci-dessus, sauf qu'elle est é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 ce qui suit:
$("#myDiv").visibleHeight();