在 JavaScript 中确定鼠标指针位于哪个元素之上

IT技术 javascript dom mouse
2021-01-31 02:17:00

我想要一个函数来告诉我鼠标光标在哪个元素上。

因此,例如,如果用户的鼠标悬停在此文本区域(带有 id wmd-input)上,则调用window.which_element_is_the_mouse_on()在功能上等同于$("#wmd-input")

6个回答

演示

有一个非常酷的函数叫做document.elementFromPoint它听起来像什么。

我们需要的是找到鼠标的 x 和 y 坐标,然后使用这些值调用它:

var x = event.clientX, y = event.clientY,
    elementMouseIsOver = document.elementFromPoint(x, y);

document.elementFromPoint

jQuery 事件对象

@TikhonJelvis:从这里我看到它在 IE 和 firefox 上受支持。如果你得到这两个,你通常会得到它们。MSDN MDN
2021-03-13 02:17:00
@HoraceLoeb 在不捕捉事件的情况下不可能获得鼠标坐标。看到这个SO问题进一步解释
2021-03-16 02:17:00
答案没有解释什么event是,以及它是如何形成的
2021-03-27 02:17:00
惊人的。有没有办法在不捕获事件的情况下获取鼠标的坐标?(可能不是我假设)。如果这是不可能的,那么不幸的是,我不认为这种方法比event.target或其他方法更好
2021-03-30 02:17:00
这是一种奇怪的方法。如果你赶上一个事件,为什么不直接使用event.target
2021-04-12 02:17:00

在较新的浏览器中,您可以执行以下操作:

document.querySelectorAll( ":hover" );

这将为您提供鼠标当前按文档顺序悬停的项目的 NodeList。NodeList 中的最后一个元素是最具体的,前面的每个元素都应该是父级、祖级等等。

我有一种感觉,这种表现很糟糕.. 调用它mousemove可能会损害性能
2021-03-18 02:17:00
(function(){ var q = document.querySelectorAll(":hover"); return q[q.length-1]; })()
2021-04-03 02:17:00
当我<li>在其他<li>元素拖动一段时间时,这似乎不起作用
2021-04-06 02:17:00
我创建了一个小提琴,$(':hover')但它基本上是一样的:jsfiddle.net/pmrotule/2pks4tf6
2021-04-11 02:17:00

虽然以下内容可能实际上并没有回答问题,因为这是谷歌搜索的第一个结果(谷歌人可能不会问完全相同的问题:),希望它能提供一些额外的输入。

实际上有两种不同的方法可以获取鼠标当前所在的所有元素的列表(对于较新的浏览器,也许):

“结构化”方法 - 升序 DOM 树

正如在dherman 的回答中,可以打电话

var elements = document.querySelectorAll(':hover');

然而,这假设只有孩子会覆盖他们的祖先,这通常是这种情况,但一般情况下并非如此,尤其是在处理 SVG 时,其中 DOM 树的不同分支中的元素可能相互重叠。

“视觉”方法——基于“视觉”重叠

这个方法用于document.elementFromPoint(x, y)查找最顶层元素,暂时隐藏它(因为我们在同一上下文中立即恢复它,浏览器实际上不会渲染这个),然后继续查找第二个顶层元素......看起来有点hacky,但是当树中存在相互遮挡的兄弟元素时,它会返回您期望的内容。请找到这篇文章以获取更多详细信息,

function allElementsFromPoint(x, y) {
    var element, elements = [];
    var old_visibility = [];
    while (true) {
        element = document.elementFromPoint(x, y);
        if (!element || element === document.documentElement) {
            break;
        }
        elements.push(element);
        old_visibility.push(element.style.visibility);
        element.style.visibility = 'hidden'; // Temporarily hide the element (without changing the layout)
    }
    for (var k = 0; k < elements.length; k++) {
        elements[k].style.visibility = old_visibility[k];
    }
    elements.reverse();
    return elements;
}

尝试两者,并检查它们的不同回报。

Document.elementsFromPoint(x, y) stackoverflow.com/a/31805883/1059828
2021-03-13 02:17:00
这是非常有用的。正是我要找的。正如你所说, querySelectorAll 并不适用于所有场景。
2021-03-14 02:17:00
这对我帮助很大。谢谢@herrlich10。令人惊讶的是,您的代码也处理嵌套子元素的情况。
2021-03-23 02:17:00
@herrlich10 对于developer.mozilla.org/en-US/docs/Web/API/Document /... 来说,这似乎是一个不错的 polyfill 如果该 API 存在于您支持的浏览器集中,我认为您可以使用它。
2021-03-31 02:17:00
BUG:当可见性被动画时,最终陷入无限循环,例如。什么时候transition: all 1s用来
2021-04-11 02:17:00

elementFromPoint()只获取 DOM 树中的第一个元素。这主要是没有足够的开发人员的需求。要在当前鼠标指针位置获取多个元素,这是您需要的功能:

document.elementsFromPoint(x, y) . // Mind the 's' in elements

这将返回给定点下所有元素对象的数组。只需将鼠标 X 和 Y 值传递给此函数。

更多信息在这里:DocumentOrShadowRoot.elementsFromPoint()

对于不受支持的非常旧的浏览器,您可以使用此答案作为后备。

它现在在 2018 年得到了很好的支持。
2021-03-14 02:17:00

以下代码将帮助您获取鼠标指针的元素。结果元素将显示在控制台中。

document.addEventListener('mousemove', function(e) {
    console.log(document.elementFromPoint(e.pageX, e.pageY)); 
})
这需要光标移动。尽可能接近,这不是这里要问的问题。
2021-03-19 02:17:00
如果页面滚动则不起作用。使用e.clientXande.clientY代替(在 Firefox 59 上测试)。
2021-03-20 02:17:00