Получите видимую высоту div с помощью jQuery
Мне нужно получить видимую высоту div в пределах прокручиваемой области. Я считаю себя довольно приличным с jQuery, но это полностью отбрасывает меня.
Скажем, у меня есть красный div в черной обертке:
![oiFk3n4.png]()
На графике выше функция jQuery вернет 248, видимую часть div.
![qzHJLZo.png]()
Как только пользователь прокручивает верхнюю часть div, как и в приведенном выше графике, он сообщает 296.
![m8lkMcj.png]()
Теперь, как только пользователь прокрутит прокрутку div, он снова сообщит об этом 248.
Очевидно, что мои номера не будут такими же четкими и ясными, как в этой демонстрации, или я бы просто написал код для этих чисел.
У меня есть немного теории:
- Получить высоту окна
- Получить высоту div
- Получить начальное смещение div из верхней части окна
- Получить смещение, когда пользователь прокручивает.
- Если смещение положительное, это означает, что верхняя часть div все еще видна.
- Если он отрицательный, верхняя часть div затмевается окном. На этом этапе div может либо занимать всю высоту окна, либо нижняя часть div может показывать
- Если нижняя часть div отображается, найдите промежуток между ним и нижней частью окна.
Это кажется довольно простым, но я просто не могу обернуть вокруг него голову. Завтра утром я сделаю очередной треск; Я просто подумал, что некоторые из вас, гениев, могут помочь.
Спасибо!
ОБНОВЛЕНИЕ: Я понял это самостоятельно, но похоже, что один из ответов ниже более изящный, поэтому я буду использовать это вместо этого. Для любопытных, вот что я придумал:
$(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);
}
}
});
Ответы
Ответ 1
Вот быстрая и грязная концепция. Он в основном сравнивает offset().top
элемента с вершиной окна, а offset().top + height()
- в нижней части окна:
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 - небольшое обновление, которое также выполняет логику при изменении размера окна.
Ответ 2
Рассчитайте количество пикселей, которое элемент (высота) находится в окне просмотра
Скриншот демо
Эта маленькая функция, которую я создал, вернет количество px
, элемент будет виден в (вертикальном) видовом экране:
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) : (b<H?b:H));
}
Используйте как:
$(window).on("scroll resize", function(){
console.log( inViewport($('#elementID')) ); // n px in viewport
});
, чтобы он.
jQuery .inViewport()
Плагин
jsFiddle demo
из вышесказанного вы можете извлечь логику и создать такой плагин, как этот:
/**
* 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) : (b<H?b:H)));
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
Использовать как:
$("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
ваши селекторы будут динамически слушать окна scroll
и resize
, но также возвращать начальное значение в DOM, готовое через первый аргумент функции обратного вызова px
.
Ответ 3
Ниже приведена версия подхода Рори, за исключением того, что она написана как плагин jQuery. Он может иметь более общую применимость в этом формате. Отличный ответ, Рори - спасибо!
$.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
}
Можно вызвать со следующим:
$("#myDiv").visibleHeight();