使用 jQuery 获取 div 的可见高度
Posted
技术标签:
【中文标题】使用 jQuery 获取 div 的可见高度【英文标题】:Get the visible height of a div with jQuery 【发布时间】:2014-09-06 06:34:22 【问题描述】:我需要检索可滚动区域内 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);
);
【问题讨论】:
我会研究 vh 单位。 1vh = 视口高度的 1/100。您可能会找到解决方案。找到视口的高度、元素的高度、元素的位置和滚动位置,并据此计算。 假设内部 DIV 上有边距,周围都说“10px”。我会检测滚动高度以查看它是否已通过“10”,然后我将获取父元素的高度,然后根据它的滚动高度减去它。 如果一切都失败了,我刚刚遇到了这个脚本,它看起来可以满足您的需要:larsjung.de/fracs 【参考方案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(`Visible height of div: $visibleBottom - visibleToppx`);
$(window).on('scroll resize', getVisible).trigger('scroll');
html,
body
margin: 100px 0;
#foo
height: 1000px;
background-color: #C00;
width: 200px;
margin: 0 auto;
#notification
position: fixed;
top: 0;
left: 0;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="foo"></div>
<div id="notification"></div>
如有必要,逻辑可以更简洁,我刚刚为这个示例声明了单独的变量,以使计算尽可能清晰。
【讨论】:
我在为多个div
s 设置此设置时遇到问题,而无需重复代码。有没有办法做到这一点?
@Rev 给你:jsfiddle.net/b5DGj/1。我将每个元素与其自己的函数调用分开。你甚至可以更进一步,定义一个插件来为你做这件事。
我稍微重写了@RoryMcCrossan 的 jQuery 插件功能方法,并将其作为答案发布在下面 - 它可能在该格式中具有更普遍的适用性。
有时一个元素会因为溢出或父元素而被部分隐藏,不管“窗口”是什么【参考方案2】:
计算一个元素(高度)在视口中的像素数
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
);
就是这样。
jQuery .inViewport()
插件
jsFiddle demo
从上面你可以提取逻辑并创建一个像这样的插件:
/**
* inViewport jQuery plugin by Roko C.B.
* http://***.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 就绪时的初始值。
【讨论】:
要在 android Chrome 上工作,您可能需要将<meta name="viewport" content="width=your_size">
添加到 head html 部分。
@userlond 感谢您的贡献,但我不确定content="width=1259"
是否适合大多数人。你试过content="width=device-width, initial-scale=1"
吗?
网站具有固定宽度的旧模板并且没有响应...我认为您的建议对大多数人来说都可以。所以澄清一下:如果 Roko C. Buljan 的解决方案不起作用,请尝试添加 <meta name="viewport" content="your_content">
声明 :)
这太棒了,与我一直在寻找的东西如此接近。如何计算从元素底部到窗口底部的距离?所以我可以在你看到内容结尾之前加载更多内容。例如,如果 windowBot 的 elBottom
@Thom 好吧,上面的方法不返回任何其他特定值(它可以扩展为返回更多的东西,而不仅仅是visible height px
,比如一个对象。看到这个小提琴有这样的想法: jsfiddle.net/RokoCB/6xjq5gyy(打开开发者控制台查看日志)【参考方案3】:
这是上述 Rory 方法的一个版本,除了编写为用作 jQuery 插件。它在该格式中可能具有更普遍的适用性。很好的答案,Rory - 谢谢!
$.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
【讨论】:
当窗口变大并且块可以容纳时不要工作。这就是为什么我们需要重置块高度: $(this).css('height', ''); jsfiddle.net/b5DGj/144以上是关于使用 jQuery 获取 div 的可见高度的主要内容,如果未能解决你的问题,请参考以下文章
jQuery 如何获取到隐藏元素的高度?或者在dom元素可见性改变时能触发个事件也行。
JQuery元素滚动定位及获取元素的scrollTop,clientHeight,scrollHeight