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

确定JavaScript中鼠标指针位于哪个元素之上,javascript,dom,mouse,Javascript,Dom,Mouse,我想要一个函数,告诉我鼠标光标在哪个元素上 因此,例如,如果用户的鼠标位于id为wmd input的文本区域上,则调用window.which\u element\u是\u mouse\u上的\u将在功能上等同于$wmd input。您可以在一些合适的祖先上查看mouseover事件的目标: var currentElement = null; document.addEventListener('mouseover', function (e) { currentElement =

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


因此,例如,如果用户的鼠标位于id为wmd input的文本区域上,则调用window.which\u element\u是\u mouse\u上的\u将在功能上等同于$wmd input。

您可以在一些合适的祖先上查看mouseover事件的目标:

var currentElement = null;

document.addEventListener('mouseover', function (e) {
    currentElement = e.target;
});
有一个非常酷的函数叫做document.elementFromPoint,它可以实现它听起来的功能

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

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

让我首先说,我不建议使用我将要建议的方法。最好使用事件驱动开发,只将事件绑定到您感兴趣的元素,以了解鼠标是否已结束mouseover、mouseout、mouseenter、mouseleave等

如果您必须能够知道鼠标在哪个元素上,那么您需要编写一个函数,将mouseover事件绑定到DOM中的所有内容,然后将当前元素存储在某个变量中

你可以这样做:

window.which_element_is_the_mouse_on = (function() {

    var currentElement;

    $("body *").on('mouseover', function(e) {
        if(e.target === e.currentTarget) {
            currentElement = this;
        }
    });

    return function() {
        console.log(currentElement);
    }
}());
基本上,我已经创建了一个即时函数,它在所有元素上设置事件,并在闭包中存储当前元素,以最小化您的占用空间

下面是一个正在运行的演示,它调用window.which_element_是鼠标,并将鼠标当前移动到控制台的元素记录下来

document.addEventListener('mousemove', function(e) {
    console.log(document.elementFromPoint(e.pageX, e.pageY)); 
})

鼠标悬停事件气泡,因此您可以在主体上放置一个侦听器,等待它们出现气泡,然后抓取event.target或event.src元素:


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

document.querySelectorAll( ":hover" );

这将为您提供一个节点列表,其中列出了鼠标当前在文档顺序上的项目。节点列表中的最后一个元素是最具体的,前面的每一个元素都应该是父母、祖父母等等。

虽然下面的内容可能没有真正回答这个问题,因为这是谷歌搜索的第一个结果,谷歌搜索者可能不会问完全相同的问题:,希望它能提供一些额外的输入

<!-- One simple solution to your problem could be like this: -->

<div>
<input type="text" id="fname" onmousemove="javascript: alert(this.id);" />
<!-- OR -->
<input type="text" id="fname" onclick="javascript: alert(this.id);" />
</div>
<!-- Both mousemove over the field & click on the field displays "fname"-->
<!-- Works fantastic in IE, FireFox, Chrome, Opera. -->
<!-- I didn't test it for Safari. -->
实际上,有两种不同的方法可以获取鼠标当前用于较新浏览器的所有元素的列表,可能是:

结构化方法&提升DOM树 就像在美国一样,你可以打电话

var elements = document.querySelectorAll(':hover');
但是,这假设只有子元素会覆盖它们的祖先,这通常是这样的,但通常不是这样,特别是在处理SVG时,DOM树的不同分支中的元素可能会相互重叠

基于视觉重叠的视觉方法 此方法使用document.elementFromPointx,y查找最顶端的元素,暂时隐藏它,因为我们在同一上下文中立即恢复它,浏览器将不会实际渲染它,然后继续查找第二个最顶端的元素。。。看起来有点粗糙,但当树中存在相互遮挡的兄弟元素时,它会返回您期望的结果。请查找以了解更多详细信息

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;
}
尝试这两种方法,并检查它们的不同返回。

当鼠标移动时,mousemove DOM事件的目标是光标下最上面的DOM元素:

(function(){
    //Don't fire multiple times in a row for the same element
    var prevTarget=null;
    document.addEventListener('mousemove', function(e) {
        //This will be the top-most DOM element under cursor
        var target=e.target;
        if(target!==prevTarget){
            console.log(target);
            prevTarget=target;
        }
    });
})();
这类似于@Philip Walton的解决方案,但不需要jQuery或setInterval。

elementFromPoint只获取DOM树中的第一个元素。这对于开发人员的需求来说是远远不够的。要在当前鼠标指针位置获取多个元素,您需要以下功能:

document.elementsFromPoint(x, y) . // Mind the 's' in elements
这将返回给定点下所有元素对象的数组。 只需将鼠标的X和Y值传递给此函数

详情如下:


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

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

document.addEventListener('mousemove', function(e) {
    console.log(document.elementFromPoint(e.pageX, e.pageY)); 
})

您可以使用此选择器在鼠标下移动对象,然后将其作为jQuery对象进行操作:

$(':hover').last();

对于那些可能仍在挣扎的人,这里有一个解决方案。您希望在要检测的子元素的“父”元素上添加鼠标悬停事件。下面的代码向您展示了如何进行此操作

const wrapper = document.getElementById('wrapper') //parent element
const position = document.getElementById("displaySelection")

wrapper.addEventListener('mousemove', function(e) {
  let elementPointed = document.elementFromPoint(e.clientX, e.clientY)

  console.log(elementPointed)
});
演示:D 在代码段窗口中移动鼠标:D

document.addEventListener'mouseover',函数e{ 您所在的console.log,e.target.tagName; };
@TikhonJelvis:从我看来IE和firefox都支持它。如果你得到了那两个,你通常会得到全部。令人惊叹的有没有办法在不捕捉事件的情况下获得鼠标的坐标?我想可能不是。如果这是不可能的,那么不幸的是,我不认为这个方法比event.target或event.target更好whatever@HoraceLoeb如果不捕获事件,则无法获取鼠标坐标。请参阅进一步解释,这是一种奇怪的方式。若你们捕捉到一个事件,为什么不直接使用event.target呢?答案并没有解释什么是事件,以及它是如何在我还在的时候出现在beThis身上的
在其他元素上拖动一段时间。我用$':hover'创建了一个小提琴,但基本上是一样的:函数{var q=document.queryselectoral:hover;return q[q.length-1];}我感觉这的性能很糟糕。。在mousemove上打电话可能会影响性能我为你在被删除的问题上受到的不好的对待道歉。就我个人而言,我更希望这个问题不被删除。在我看来,当它即将不公平地关闭时,我正计划投票重新打开它。然而,考虑到反对票的数量,如果你选择删除它,我理解。这对我帮助很大。谢谢@herrlich10。令人惊讶的是,您的代码也处理嵌套子元素的情况。这非常有用。正是我想要的。正如您所说,querySelectorAll并不是在所有情况下都有效。@herrlich10这似乎是一个不错的多填充。如果您支持的浏览器集中存在该API,我想您可以使用它。感谢您的帮助-尽管没有元素,但与Expected的效果相当。如果与getElementsFromPoint兼容,则相反,但在我的chrome测试中,每次调用速度慢了18-20ms,这使得我很难在拖动过程中找到拖放目标的场景中使用,因为使用更基本的事件驱动方法是不可行的。请参阅Document.elementsFromPointx,y欢迎使用堆栈溢出!请添加一些解释,说明此代码为何有助于OP。这将有助于提供未来观众可以从中学习的答案。有关更多信息,请参阅。还有,鼠标下?鼠标下的对象是什么?你的意思是鼠标下的物体吗?还是别的?这需要光标移动。尽可能接近,这不是这里要问的问题。如果页面被滚动,则不起作用。使用e.clientX和e.clientY代替在Firefox 59上测试的版本。虽然我自己使用通用事件处理程序,但这在资源方面比document.elementFromPointx,y更昂贵。它在2018年得到了很好的支持。