Answers:
有一个很酷的函数document.elementFromPoint
,它听起来像什么。
我们需要找到鼠标的x和y坐标,然后使用这些值进行调用:
var x = event.clientX, y = event.clientY,
elementMouseIsOver = document.elementFromPoint(x, y);
event.target
或什么
event.target
?
event
是什么,以及它是如何变成的
在较新的浏览器中,您可以执行以下操作:
document.querySelectorAll( ":hover" );
这将为您提供一个NodeList,它按文档顺序显示鼠标当前位于的项目。NodeList中的最后一个元素是最具体的,前面的每个元素都应该是父级,祖父母级,依此类推。
<li>
在其他<li>
元素上拖动一会儿时,这似乎不起作用。
$(':hover')
但是基本上是一样的:jsfiddle.net/pmrotule/2pks4tf6
(function(){ var q = document.querySelectorAll(":hover"); return q[q.length-1]; })()
mousemove
可能会损害性能
尽管以下内容可能并未真正回答问题,但由于这是谷歌搜索的第一个结果(Google员工可能不会问完全相同的问题:),希望它会提供一些额外的输入。
实际上,有两种方法可以获取鼠标当前所处的所有元素的列表(也许对于较新的浏览器而言):
就像德曼的回答一样,
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;
}
尝试两者,并检查它们的不同收益。
Document.elementsFromPoint(x, y)
stackoverflow.com/a/31805883/1059828
elementFromPoint()
仅获取DOM树中的第一个元素。这几乎不足以满足开发人员的需求。要在当前鼠标指针位置获得多个元素,这是您需要的功能:
document.elementsFromPoint(x, y) . // mind the 's' in elements
这将返回给定点下所有元素对象的数组。只需将鼠标的X和Y值传递给此函数即可。
此处的更多信息:https : //developer.mozilla.org/zh-CN/docs/Web/API/document/elementsFromPoint
对于不支持的非常旧的浏览器,您可以将此答案用作备用。
鼠标悬停事件冒泡,因此您可以将单个侦听器放在主体上,等待它们冒泡,然后抓住event.target
或event.srcElement
:
function getTarget(event) {
var el = event.target || event.srcElement;
return el.nodeType == 1? el : el.parentNode;
}
<body onmouseover="doSomething(getTarget(event));">
document.elementFromPoint(x, y)
。
<!-- 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. -->
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。
您可以使用此选择器在对象上添加鼠标,然后将其作为jquery对象操作。 $(':hover').last();
首先,我要说的是我不建议使用我将建议的方法。这是更好的使用事件驱动的开发和绑定的事件只有你有兴趣了解鼠标是否是在与元素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_is_the_mouse_on
每秒调用一次,并将鼠标当前移到控制台的内容记录在日志中。
古老的问题,但是这里为那些仍在挣扎中的人们提供了解决方案。您想要在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)
});