在 JavaScript 中,您将如何检查元素是否确实可见?
我的意思不只是检查visibility
和display
属性。我的意思是,检查元素不是
visibility: hidden
或者display: none
- 在另一个元素下面
- 滚出屏幕边缘
由于技术原因,我不能包含任何脚本。但是,我可以使用Prototype,因为它已经在页面上。
在 JavaScript 中,您将如何检查元素是否确实可见?
我的意思不只是检查visibility
和display
属性。我的意思是,检查元素不是
visibility: hidden
或者 display: none
由于技术原因,我不能包含任何脚本。但是,我可以使用Prototype,因为它已经在页面上。
对于第 2 点。
我看到没有人建议使用document.elementFromPoint(x,y)
,对我来说这是测试一个元素是否被另一个元素嵌套或隐藏的最快方法。您可以将目标元素的偏移量传递给函数。
这是elementFromPoint上的 PPK 测试页面。
来自MDN 的文档:
该
elementFromPoint()
方法(可用于 Document 和 ShadowRoot 对象)返回指定坐标(相对于视口)的最顶部 Element。
我不知道旧浏览器或不太现代的浏览器支持多少,但我正在使用这样的东西(不需要任何库):
function visible(element) {
if (element.offsetWidth === 0 || element.offsetHeight === 0) return false;
var height = document.documentElement.clientHeight,
rects = element.getClientRects(),
on_top = function(r) {
var x = (r.left + r.right)/2, y = (r.top + r.bottom)/2;
return document.elementFromPoint(x, y) === element;
};
for (var i = 0, l = rects.length; i < l; i++) {
var r = rects[i],
in_viewport = r.top > 0 ? r.top <= height : (r.bottom > 0 && r.bottom <= height);
if (in_viewport && on_top(r)) return true;
}
return false;
}
它检查元素的区域是否大于 0,然后检查元素的任何部分是否在视口内,并且它没有隐藏在另一个元素的“下方”(实际上我只检查元素中心的一个点,所以它不是 100% 有保证的——但是你可以修改脚本来遍历元素的所有点,如果你真的需要......)。
更新
修改了检查每个像素的 on_top 函数:
on_top = function(r) {
for (var x = Math.floor(r.left), x_max = Math.ceil(r.right); x <= x_max; x++)
for (var y = Math.floor(r.top), y_max = Math.ceil(r.bottom); y <= y_max; y++) {
if (document.elementFromPoint(x, y) === element) return true;
}
return false;
};
不知道性能如何:)
正如 jkl 所指出的,检查元素的可见性或显示是不够的。你必须检查它的祖先。Selenium 在验证元素的可见性时会这样做。
查看 selenium-api.js 文件中的方法 Selenium.prototype.isVisible。
http://svn.openqa.org/svn/selenium-on-rails/selenium-on-rails/selenium-core/scripts/selenium-api.js
有趣的问题。
这将是我的方法。
希望能帮助到你。
这就是我迄今为止所拥有的。它涵盖了 1 和 3。但是我仍然在为 2 苦苦挣扎,因为我对 Prototype 不太熟悉(我更像是一个 jQuery 类型的人)。
function isVisible( elem ) {
var $elem = $(elem);
// First check if elem is hidden through css as this is not very costly:
if ($elem.getStyle('display') == 'none' || $elem.getStyle('visibility') == 'hidden' ) {
//elem is set through CSS stylesheet or inline to invisible
return false;
}
//Now check for the elem being outside of the viewport
var $elemOffset = $elem.viewportOffset();
if ($elemOffset.left < 0 || $elemOffset.top < 0) {
//elem is left of or above viewport
return false;
}
var vp = document.viewport.getDimensions();
if ($elemOffset.left > vp.width || $elemOffset.top > vp.height) {
//elem is below or right of vp
return false;
}
//Now check for elements positioned on top:
//TODO: Build check for this using Prototype...
//Neither of these was true, so the elem was visible:
return true;
}