用jQuery获取div的可见高度

我需要检索可滚动区域内div的可见高度。 我认为我自己相当体面的jQuery,但这是完全抛弃我。

假设我在一个黑色包装中有一个红色的div:

在上图中,jQuery函数将返回248,div的可见部分。

一旦用户滚动超过div的顶部,如上图所示,将报告296。

现在,一旦用户滚动过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); } } }); 

这是一个快速和肮脏的概念。 它基本上将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); 

示例小提琴

编辑 – 小的更新也可以在窗口大小调整时执行逻辑。

计算元素(高度)在视口中的px数量

小提琴演示

我创build的这个微小的函数将返回一个元素在(垂直) 视口中可见的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, Ht) : (b<H?b:H)); } 

使用像:

 $(window).on("scroll resize", function(){ console.log( inViewport($('#elementID')) ); // n px in viewport }); 

而已。


jQuery .inViewport()插件

jsFiddle演示

从上面你可以提取逻辑和创build一个像这样的插件:

 /** * inViewport jQuery plugin by Roko CB * 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, Ht) : (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 

您的select器将dynamic侦听窗口scrollresize但也通过第一个callback函数参数px返回DOM准备好的初始值。

这里是上面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(); 

的jsfiddle