如何检查元素是否在屏幕之外
如何检查元素是否在屏幕之外
我需要用jQuery检查一个DIV元素是否没有超出屏幕。这些元素根据CSS属性可见并显示,但它们可能被故意放置在屏幕外面,方法是:
position: absolute; left: -1000px; top: -1000px;
我不能使用jQuery的:visible
选择器,因为该元素具有非零的高度和宽度。
我没有进行任何花哨的操作。这种绝对定位是我Ajax框架实现某些小部件的隐藏/显示的方式。
如何检查元素是否在屏幕外?
通过使用Element.getBoundingClientRect(),您可以轻松检测元素是否在视口的边界内(即在屏幕上或屏幕外):
jQuery.expr.filters.offscreen = function(el) { var rect = el.getBoundingClientRect(); return ( (rect.x + rect.width) < 0 || (rect.y + rect.height) < 0 || (rect.x > window.innerWidth || rect.y > window.innerHeight) ); };
然后,您可以以几种方式使用它:
// 返回所有在屏幕外的元素 $(':offscreen'); // 如果元素在屏幕外,则返回布尔值 $('div').is(':offscreen');
但是,如果您的元素位于可滚动的容器内部,这种方法就会出错 - 因为一个位于2屏高的DIV底部的元素始终是“屏幕外”的,因为窗口高度小于元素的offsetTop。
我无法使这个方法工作。这是我的问题(包含jsFiddle):stackoverflow.com/questions/26004098/…
如果el在body之前有定位的父元素(绝对或相对),这个方法是否有效?
你是对的,我更新了示例来解决这个问题,现在看起来好多了,并且帮助我将2行if条件减少为1行。我认为它在不同的浏览器上也适用,希望如此...
我认为这个方法即使元素部分在屏幕外也会返回true。我如何检测完全在屏幕外的元素?
请注意,目前(2017年1月),这在Chrome上不起作用,因为Element.getBoundingClientRect()的属性是top、right、bottom和left,而不是x和y。
这很有趣,因为根据规范,它应该同时包含x和y值。我想你可以分别交换left和right,但我不确定Chrome发生了什么变化。
在您的答案的基础上,我创建了一个变体,可以对部分或完全在屏幕外的元素返回true,链接在这里:https://pastebin.com/CqgWvf1a
如何检查元素是否在屏幕外的问题出现的原因是:代码中使用了错误的方法来计算元素的位置,导致无法准确判断元素是否在屏幕外。
解决方法是:将代码中的 $this.position
替换为 $(this).offset
。这样可以正确计算元素相对于文档的位置,从而准确判断元素是否在屏幕外。
以下是修正后的代码示例:
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); var d = $(document).scrollTop(); $.each($("div"), function() { var offset = $(this).offset(); //vertical if (offset.top > h + d || offset.top > h - d) { console.log($(this)); } //horizontal if (offset.left < 0 - $(this).width() || offset.left > w) { console.log($(this)); } });
有时候我们需要判断一个元素是否在屏幕外面,以便进行相应的处理。一个解决这个问题的方法是使用一个名为"jQuery Visible"的jQuery插件。这个插件可以帮助我们测试一个元素是否在浏览器可见的视口范围内,并且还会考虑浏览器的滚动位置。
使用这个插件非常简单,我们只需要使用以下代码来检查一个元素是否可见:
$('#element').visible();
我们还可以检查元素是否只是部分可见:
$('#element').visible( true);
这个插件的一个缺点是它只适用于垂直定位/滚动,但是很容易将水平定位加入其中。
这个插件非常轻量级,只需在添加它之后的几分钟内,我就能够在滚动时实现一个固定的导航栏,并且可以适应不同的屏幕大小。非常好用的建议。
这个插件非常轻量级且易于实现,解决了我在子菜单上遇到的问题。