是否可以确定 html 元素对用户是否可见?
页面有一个带有日期选择器的输入字段。如果用户单击输入字段,则会出现另一个 div,允许用户选择所需的日期。
只要日期选择器可见,它就会隐藏其后面的元素。我需要一种方法来判断元素是否隐藏。
一种方法是检查并比较
z-index
值。但如果它们被明确设置,它们总是 auto
。
另一种方法可能是检查元素是否对用户可见。但我想不出有什么办法可以做到这一点。
:visible
选择器在这种情况下不起作用,因为该元素仅对用户的眼睛隐藏,但仍然可见。
有什么建议吗?
我尝试了一种不同的方法,使用元素坐标 (
getBoundingClientRect
),然后使用 elementFromPoint
来查看元素是隐藏还是可见。
DEMO(按照右侧说明操作)
var rectPos = this.getBoundingClientRect();
var result = 0;
if (this == document.elementFromPoint(rectPos.left,
rectPos.top)) {
result++;
}
if (this == document.elementFromPoint(rectPos.left,
rectPos.bottom - 1)) {
result++;
}
if (this == document.elementFromPoint(rectPos.right - 1,
rectPos.top)) {
result++;
}
if (this == document.elementFromPoint(rectPos.right - 1, rectPos.bottom - 1)) {
result++;
}
if (result == 4) {
result = 'visible';
} else if (result == 0) {
result = 'hidden';
} else {
result = 'partially visible';
}
这可能有用。我还没有测试过。这是我在here找到的一些代码的修改版本。
function elementWithinElement(elemPossiblyCovered, elemPossiblyCovering)
{
var top = elemPossiblyCovered.offsetTop;
var left = elemPossiblyCovered.offsetLeft;
var width = elemPossiblyCovered.offsetWidth;
var height = elemPossiblyCovered.offsetHeight;
while (elemPossiblyCovered.offsetParent)
{
elemPossiblyCovered = elemPossiblyCovered.offsetParent;
top += elemPossiblyCovered.offsetTop;
left += elemPossiblyCovered.offsetLeft;
}
return (
top >= elemPossiblyCovering.offsetTop &&
left >= elemPossiblyCovering.offsetLeft &&
(top + height) <= (elemPossiblyCovering.offsetTop + elemPossiblyCovering.offsetHeight) &&
(left + width) <= (elemPossiblyCovering.offsetLeft + elemPossiblyCovering.offsetWidth)
);
}
所以它会是这样的:
if(elementWithinElement(myTextbox, theDatepickerDiv))
{
// It's hidden
}else
{
//It's visible
}
编辑:某些代码未更新。现在应该修复了。
再次编辑:修复代码并进行测试。有效!
我能想到的唯一方法是获取每个项目的偏移量并检查新项目的偏移量是否不在先前任何项目的偏移量内。显然,光是背后的理论就需要很长时间才能实现这一点。祝你好运:)
function traversParents(el, callback, depth = 10) {
let level = depth;
let parent = el.parentElement;
while (level > 0 && parent) {
const stop = callback(parent);
if (stop) break;
parent = parent.parentElement;
level--;
}
}
function findTopmost(els) {
let highest = 0;
let highestZIndex = 0;
const getZIndex = (el) => {
const computedStyle = window.getComputedStyle(el);
const isAbsolute = computedStyle.getPropertyValue('position') === 'absolute' ? 0.5 : 0;
return Number.parseInt(computedStyle.getPropertyValue('z-index')) || isAbsolute;
}
els.forEach((el, i) => {
let zIndex = getZIndex(el);
traversParents(el, (parent) => {
if (zIndex > 0) return true;
zIndex = getZIndex(parent);
}, 15);
if (zIndex > highestZIndex) {
highestZIndex = zIndex;
highest = i;
}
});
return els[highest];
}