使用书签,我想使用 jquery .hover() 将 img 元素与 mouseenter 和 mouseleave 事件的处理程序绑定(bind)在一起,但在某些情况下,鼠标事件永远不会被触发,因为 img 元素以某种方式对鼠标隐藏图像实际上是可见的:一个简单的例子是当图像被透明元素重叠时。如果您使用像 Firebug Inspector 这样的工具,您会发现很多这样的例子。
我怎样才能弄清楚这种行为?理想情况下,我想构建一个函数,根据元素是否可悬停返回 true 或 false。
感谢大家
最佳答案
问题:
真正的问题是有很多方法可以覆盖一个元素。例如,该元素是否被其他 4 个元素覆盖,而中间仅留有一个空间?我的意思的例子:
假设红色框是有问题的元素,直接位于中心的小框是直接查看该元素。
由于这些问题,确定元素是否具有任何可悬停区域可能会变得非常“昂贵”。
解决方案:
我想出了一个使用 boundingClientRect
、document.elementFromPoint
和文档滚动的解决方案。它尝试通过检查相关元素的 4 个 Angular 来快速确定,然后如果这些 Angular 返回 false,则开始按照确定的“准确性”检查整个元素。
更新:
我添加了一种方法来检查甚至不在视口(viewport)中的元素。这是通过尝试滚动元素,运行检查,然后滚动回检查开始之前的上一个位置来实现的。这种情况发生得如此之快,以至于没有发生明显的跳跃。
function getOffset(el) {
el = el.getBoundingClientRect();
return {
left: el.left + window.scrollX,
top: el.top + window.scrollY
}
}
function isElementHoverable(element) {
var pageX = window.scrollX;
var pageY = window.scrollY;
var elementXY = getOffset(element);
var accuracy = 1;
var canBeHovered = false;
window.scrollTo(elementXY.left, elementXY.top);
var box = element.getBoundingClientRect();
// try the 4 corners first
if (
element == document.elementFromPoint(box.left, box.top) ||
element == document.elementFromPoint(box.left, box.bottom - 1) ||
element == document.elementFromPoint(box.right - 1, box.top) ||
element == document.elementFromPoint(box.right - 1, box.bottom - 1)
) {
canBeHovered = true;
}
loop1:
for (let i = box.left; i < box.right; i += accuracy) {
for (let j = box.top; j < box.bottom; j += accuracy) {
if (element == document.elementFromPoint(i, j)) {
canBeHovered = true;
break loop1;
}
}
}
window.scrollTo(pageX, pageY); // Scroll back to the original position
return canBeHovered;
}
I worked up an actual example on JSFiddle (示例已更新以反射(reflect)向下滚动页面的元素),并完成了一些测试。您需要打开浏览器控制台才能查看测试结果。您可能还想首先在 Chrome 或 Firefox 中测试这一点,因为我没有在其他地方测试过这一点。
需要记住的一些事情:
如果 4 个 Angular 检查失败,那么检查元素的其余部分就会变得昂贵。 “准确度”数字越小,价格就越高。该数字决定运行检查的频率。因此,如果精度为 1
,那么它将每隔 1px 检查一次。如果数字是10
,那么它将在X和Y轴上每10px检查一次。
需要注意的是,几乎没有办法知道页面中元素的变化。您在评论中提到,某些在检查期间“阻塞”的元素可能会消失,但在用户交互时不会消失。如果没有人工智能,就没有办法知道这个功能。然而,这个函数应该根据您的选择来调用,而不仅仅是在页面加载时调用。
关于javascript - 以编程方式检测元素是否能够悬停,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40877619/