我需要在可滚动区域内检索div的可见高度。我认为自己在jQuery方面相当不错,但这完全让我失望。
假设我在黑色包装中有一个红色div:
在上图中,jQuery函数将返回248,即div的可见部分。
一旦用户滚过div的顶部,如上图所示,它将报告296。
现在,一旦用户滚过div,它将再次报告248。
显然,我的数字不会像在本演示中那样一致和清晰,或者我只是硬编码这些数字。
我有一点理论:
看起来很简单,但我无法绕过它。明天早上我会再接受一次破解;我只是想你们中的一些天才可能会有所帮助。
谢谢!
更新:我自己想出了这个,但看起来下面的答案之一更优雅,所以我将使用它。对于好奇,这是我想出的:
$(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);
}
}
});
答案 0 :(得分:53)
这是一个快速而肮脏的概念。它基本上将元素的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);
编辑 - 小型更新,以便在调整窗口大小时执行逻辑。
答案 1 :(得分:45)
<强> Fiddle demo 强>
这个微小的函数将返回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) : Math.min(b, H));
}
使用类似:
$(window).on("scroll resize", function(){
console.log( inViewport($('#elementID')) ); // n px in viewport
});
就是这样。
.inViewport()
插件从上面你可以提取逻辑并创建一个像这样的插件:
/**
* 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));
使用类似:
$("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
,但也会通过第一个回调函数参数px
返回DOM的初始值。
答案 2 :(得分:9)
这是上面Rory方法的一个版本,除了写为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();