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

发布于 2024-12-26 15:39:24 字数 178 浏览 1 评论 0原文

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

因此,例如,如果用户的鼠标位于此文本区域上(ID为wmd-input),则调用window.which_element_is_the_mouse_on()在功能上等同于$ (“#wmd-input”)

I want a function that tells me which element the mouse cursor is over.

So, for example, if the user's mouse is over this textarea (with id wmd-input), calling window.which_element_is_the_mouse_on() will be functionally equivalent to $("#wmd-input").

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

木有鱼丸 2025-01-02 15:39:25

elementFromPoint() 仅获取 DOM 树中的第一个元素。这基本上不足以满足开发人员的需求。要在当前鼠标指针位置获取多个元素,您需要使用以下函数:

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

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

更多信息如下:DocumentOrShadowRoot.elementsFromPoint()

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

elementFromPoint() gets only the first element in DOM tree. This is mostly not enough for developers needs. To get more than one element at e.g. the current mouse pointer position, this is the function you need:

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

This returns an array of all element objects under the given point.
Just pass the mouse X and Y values to this function.

More information is here: DocumentOrShadowRoot.elementsFromPoint()

For very old browsers which are not supported, you may use this answer as a fallback.

花间憩 2025-01-02 15:39:25

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

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

The following code will help you to get the element of the mouse pointer. The resulted elements will display in the console.

document.addEventListener('mousemove', function(e) {
    console.log(document.elementFromPoint(e.pageX, e.pageY)); 
})
涙—继续流 2025-01-02 15:39:25

鼠标悬停事件会冒泡,因此您可以在主体上放置一个侦听器并等待它们冒泡,然后获取 event.targetevent.srcElement

function getTarget(event) {
    var el = event.target || event.srcElement;
    return el.nodeType == 1? el : el.parentNode;
}

<body onmouseover="doSomething(getTarget(event));">

Mouseover events bubble, so you can put a single listener on the body and wait for them to bubble up, then grab the event.target or event.srcElement:

function getTarget(event) {
    var el = event.target || event.srcElement;
    return el.nodeType == 1? el : el.parentNode;
}

<body onmouseover="doSomething(getTarget(event));">
两仪 2025-01-02 15:39:25

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

var currentElement = null;

document.addEventListener('mouseover', function (e) {
    currentElement = e.target;
});

这是一个演示.

You can look at the target of the mouseover event on some suitable ancestor:

var currentElement = null;

document.addEventListener('mouseover', function (e) {
    currentElement = e.target;
});

Here’s a demo.

妄断弥空 2025-01-02 15:39:25

演示 :D

在代码片段窗口中移动鼠标 :D

<script>
document.addEventListener('mouseover', function (e) {
    console.log ("You are in ", e.target.tagName);
});
</script>

Demo :D

Move your mouse in the snippet window :D

<script>
document.addEventListener('mouseover', function (e) {
    console.log ("You are in ", e.target.tagName);
});
</script>

智商已欠费 2025-01-02 15:39:25
<!-- 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. -->
<!-- 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. -->
轻许诺言 2025-01-02 15:39:25

2022 更新:

document.elementsFromPoint()(注意 elements 中的 's')与所有主要浏览器兼容。它基本上与 elementFrompoint 执行相同的操作,但按 DOM 顺序检索所有元素。

Mozilla 有一个很好的例子:

HTML

<div>
  <p>Some text</p>
</div>
<p>Elements at point 30, 20:</p>
<div id="output"></div>

JavaScript

let output = document.getElementById("output");
if (document.elementsFromPoint) {
  let elements = document.elementsFromPoint(30, 20);
  for (var i = 0; i < elements.length; i++) {
    output.textContent += elements[i].localName;
    if (i < elements.length - 1) {
      output.textContent += " < ";
    }
  }
} else {
  output.innerHTML = "<span style=\"color: red;\">" +
     "Browser does not support <code>document.elementsFromPoint()</code>" +
     "</span>";
}

Output

Some text

Elements at point 30, 20:

p < div < body < html

https:/ /developer.mozilla.org/en-US/docs/Web/API/Document/elementsFromPoint

2022 Update:

document.elementsFromPoint() (Note the 's' in elements) is compatible with all major browsers. It basically does the same thing that elementFrompoint does, but retrieves all the elements in DOM order.

Mozilla has a good example of this:

HTML

<div>
  <p>Some text</p>
</div>
<p>Elements at point 30, 20:</p>
<div id="output"></div>

JavaScript

let output = document.getElementById("output");
if (document.elementsFromPoint) {
  let elements = document.elementsFromPoint(30, 20);
  for (var i = 0; i < elements.length; i++) {
    output.textContent += elements[i].localName;
    if (i < elements.length - 1) {
      output.textContent += " < ";
    }
  }
} else {
  output.innerHTML = "<span style=\"color: red;\">" +
     "Browser does not support <code>document.elementsFromPoint()</code>" +
     "</span>";
}

Output

Some text

Elements at point 30, 20:

p < div < body < html

https://developer.mozilla.org/en-US/docs/Web/API/Document/elementsFromPoint

落日海湾 2025-01-02 15:39:25

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

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

You can use this selector to undermouse object and then manipulate it as a jQuery object:

$(':hover').last();
子栖 2025-01-02 15:39:25

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。

The target of the mousemove DOM event is the top-most DOM element under the cursor when the mouse moves:

(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;
        }
    });
})();

This is similar to @Philip Walton's solution, but doesn't require jQuery or a setInterval.

樱花坊 2025-01-02 15:39:25

对于那些可能仍在苦苦挣扎的人来说,这是一个解决方案。您想要在要检测的子元素的“父”元素上添加 mouseover 事件。下面的代码向您展示了如何进行操作。

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)
});

CodePen 上的演示

Here's a solution for those that may still be struggling. You want to add a mouseover event on the 'parent' element of the child element(s) you want detected. The below code shows you how to go about it.

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)
});

Demo on CodePen

颜漓半夏 2025-01-02 15:39:25

我知道这是一个老问题。我想添加我的解决方案。

function pointerOverElement( element, { clientX: x, clientY: y } ){
    const rect = element.getBoundingClientRect();
    return rect.left <= x && rect.right >= x && rect.top <= y && rect.bottom >= y;
}

然后只需在您的活动中使用它即可:

pointerOverElement( element, e );

I know this is an old question. I wanted to add my solution in.

function pointerOverElement( element, { clientX: x, clientY: y } ){
    const rect = element.getBoundingClientRect();
    return rect.left <= x && rect.right >= x && rect.top <= y && rect.bottom >= y;
}

then just use it in your events as:

pointerOverElement( element, e );
暗恋未遂 2025-01-02 15:39:25

首先我要说的是,我不建议使用我即将建议的方法。最好使用事件驱动开发,并将事件仅绑定到您感兴趣的元素,通过 mouseovermouseout了解鼠标是否已结束mouseentermouseleave 等。

如果您绝对必须能够知道鼠标位于哪个元素上,则需要编写一个绑定的函数鼠标悬停事件处理 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_is_the_mouse_on 并将鼠标当前所在的元素记录到控制台。

http://jsfiddle.net/LWFpJ/1/

Let me start out by saying that I don't recommend using the method I'm about to suggest. It's much better to use event driven development and bind events only to the elements you're interested in knowing whether or not the mouse is over with mouseover, mouseout, mouseenter, mouseleave, etc.

If you absolutely must have the ability to know which element the mouse is over, you'd need to write a function that binds the mouseover event to everything in the DOM, and then store whatever the current element is in some variable.

You could so something like this:

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);
    }
}());

Basically, I've created an immediate function which sets the event on all elements and stores the current element within the closure to minimize your footprint.

Here's a working demo that calls window.which_element_is_the_mouse_on every second and logs what element the mouse is currently over to the console.

http://jsfiddle.net/LWFpJ/1/

神爱温柔 2025-01-02 15:39:24

DEMO

有一个非常酷的函数,名为 document.elementFromPoint,它的作用就像听起来的那样。

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

document.addEventListener('mousemove', e => {
  console.clear()
  console.log( document.elementFromPoint(e.clientX, e.clientY) )
}, {passive: true})
[class^='level']{
  width: 100px;
  height: 100px;
  padding: 15px;
  background: #00000033;
}
<div class='level-1'>
  <div class='level-2'>
    <div class='level-3'>
      Hover
    </div>
  </div>
</div>

document.elementFromPoint

< a href="http://api.jquery.com/category/events/event-object/" rel="noreferrer">jQuery 事件对象

DEMO

There's a really cool function called document.elementFromPoint which does what it sounds like.

What we need is to find the x and y coords of the mouse and then call it using those values:

document.addEventListener('mousemove', e => {
  console.clear()
  console.log( document.elementFromPoint(e.clientX, e.clientY) )
}, {passive: true})
[class^='level']{
  width: 100px;
  height: 100px;
  padding: 15px;
  background: #00000033;
}
<div class='level-1'>
  <div class='level-2'>
    <div class='level-3'>
      Hover
    </div>
  </div>
</div>

document.elementFromPoint

jQuery event object

白龙吟 2025-01-02 15:39:24

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

document.querySelectorAll( ":hover" );

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

In newer browsers, you could do the following:

document.querySelectorAll( ":hover" );

That'll give you a NodeList of items that the mouse is currently over in document order. The last element in the NodeList is the most specific, each preceding one should be a parent, grandparent, and so on.

时光暖心i 2025-01-02 15:39:24

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

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

“结构”方法 - 升序 DOM 树

dherman 的答案,可以调用

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

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

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

此方法使用 document.elementFromPoint(x, 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;
}

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

Although the following may not actually answering the question, since this is the first result of googling (the googler may not asking exactly the same question:), hope it will provide some extra input.

There are actually two different approaches to get a list of all elements the mouse is currently over (for newer browsers, perhaps):

The "structural" approach - Ascending DOM tree

As in dherman's answer, one can call

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

However, this assumes that only children will overlay their ancestors, which is usually the case, but not true in general, especially when dealing with SVG where element in different branches of the DOM tree may overlap each other.

The "visual" approach - Based on "visual" overlapping

This method uses document.elementFromPoint(x, y) to find the topmost element, temporarily hide it (since we recover it immediately in the same context, the browser will not actually renders this), then go on to find the second topmost element... Looks a little hacky, but it returns what you expect when there are, e.g., siblings elements in a tree occluding each other. Please find this post for more details,

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;
}

Try both, and check their different returns.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文