以编程方式检测元素是否能够被徘徊

时间:2016-11-29 23:22:55

标签: javascript jquery html dom mousehover

使用bookmarklet我想使用jquery .hover()将img元素与mouseenter和mouseleave事件的处理程序绑定,但在某些情况下,永远不会触发鼠标事件,因为img元素以某种方式隐藏在鼠标中尽管图像实际上是可见的:一个简单的例子是当它与透明元素重叠时。如果您使用像firebug检查器这样的工具,您会发现许多这样的例子。

我怎样才能弄清楚这种行为?理想情况下,我想构建一个函数,它将返回true或false,具体取决于元素是否可以恢复。

感谢所有

1 个答案:

答案 0 :(得分:5)

问题:

真正的问题是,有很多方法可以涵盖一个元素。例如,元素是否覆盖了4个其他元素,中间只有一个空格?我的意思是:

enter image description here

假设红色框是有问题的元素,直接在中心的小框是直接查看元素。

由于这些问题,它可能变得非常昂贵而且#34;确定该元素是否具有任何可收回的区域。

解决方案:

我想出了一个使用boundingClientRectdocument.elementFromPoint和文档滚动的解决方案。它试图快速确定,通过检查有问题的元素的4个角,然后如果它们返回假,则开始通过确定的"准确度来检查整个元素。

<强>更新

我添加了一种方法来检查视口中不均匀的元素。这通过尝试滚动元素,运行检查,然后在检查开始之前滚动回到上一个位置来工作。这种情况发生得如此之快,以至于没有发生可见的跳跃。

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(示例已更新以反映在页面中向下滚动的元素),并完成了几项测试。您需要打开浏览器控制台才能看到测试结果。您可能还想先在Chrome或Firefox中测试一下,因为我没有在此之外对此进行测试。

要记住的一些事项:

如果4角检查失败,那么检查元素的其余部分会很昂贵。准确度越小&#34;数字,它越贵。该数字决定了运行支票的频率。因此,如果准确度为1,那么它将检查每1px。如果数字是10,那么它将检查X轴和Y轴上的每10px。

应该注意的是,几乎没有办法知道页面中元素的变化。你在评论中提到某些元素可能会消失,因为它们会阻塞&#34;在检查期间,但不是在用户进行交互时。没有办法知道这个功能缺少AI。但是,此功能是根据您的选择调用的,而不仅仅是页面加载。