javascript MouseOver/MouseOut EventListener 继承到子节点?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8399408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MouseOver/MouseOut EventListener inheriting to child nodes?
提问by kwh
Edit: Solution
编辑:解决方案
Thanks to Gabyfor the help in finding a solution! Didn't quite work exactly how I wanted it to, found a better solution modified from the answers. What I do is only execute the mouseover/mouseout functions when the two elements (target and related target) do not share a parent.
感谢Gaby帮助找到解决方案!并没有完全按照我想要的方式工作,从答案中找到了一个更好的解决方案。我所做的只是在两个元素(目标和相关目标)不共享父元素时执行 mouseover/mouseout 函数。
Just modified Gaby's example a bit and have everything working great. As long as your popup is within the same div element as whatever spawns it (even if it's outside the main contents you can append it with overflow visible) and you don't go between non-shared elements on the way over to it, it'll stay alive.
只是稍微修改了 Gaby 的例子,一切都很好。只要您的弹出窗口与生成它的任何内容位于同一个 div 元素内(即使它在主要内容之外,您也可以将其附加为溢出可见)并且您不会在到达它的途中在非共享元素之间移动,它会活下去。
divContents.addEventListener('mouseover', mouseEnter(showPopup, divContents));
divContents.addEventListener('mouseout', mouseEnter(hidePopup, divContents));
Now, the modified mouseEnter...
现在,修改后的 mouseEnter...
function mouseEnter(_fn, _parent) {
return function(_evt) {
if(!shareParent(_evt.target, _evt.relatedTarget, _parent)) {
_fn.call(this, _evt);
}
}
};
function shareParent(_object1, _object2, _parent) {
if (_object1 === _object2) {
return true;
}
while (_object1 && _object1 !== _parent) {
_object1 = _object1.parentNode;
}
while (_object2 && _object2 !== _parent) {
_object2 = _object2.parentNode;
}
return _object1 === _object2;
}
Solved my problem A-OK, because what I want to fire for mouseover and mouseout events will only happen when the elements don't share a parent - exactly how I intended on displaying the popups anyhow.
解决了我的问题 A-OK,因为我想为 mouseover 和 mouseout 事件触发的事件只会在元素不共享父元素时发生 - 无论如何我打算如何显示弹出窗口。
Thanks again for the code example from Gaby, though!
不过,再次感谢 Gaby 的代码示例!
NOTE:No error checking for parent validity in shareParent function, haven't checked but it should always return true when it gets to the top of the tree (assuming the _parent isn't actually a parent of either _object1 or _object2). So make sure the parent object you pass to it is valid.
注意:在 shareParent 函数中没有检查父有效性的错误,没有检查但是当它到达树的顶部时它应该总是返回 true(假设 _parent 实际上不是 _object1 或 _object2 的父)。因此,请确保您传递给它的父对象是有效的。
Original Question:
原问题:
I'm having a problem in JavaScript right now.
我现在在 JavaScript 中遇到了问题。
I'm trying to create a div Element that pops up dynamically when something has a mouseover. The div is created directly adjacent to the object that spawns it.
我正在尝试创建一个 div 元素,该元素在鼠标悬停时动态弹出。div 直接与生成它的对象相邻创建。
divCreator.addEventListener('mouseover', createPopup, true);
divCreator.addEventListener('mouseout', hidePopup, true);
That creates the popup. Now, in the popup, when I create it, I run this before I append it to the document:
这会创建弹出窗口。现在,在弹出窗口中,当我创建它时,我在将它附加到文档之前运行它:
divPopup.addEventListener('mouseover', createPopup, true);
divPopup.addEventListener('mouseout', hidePopup, true);
This ensures that if I mouseover the popup, it keeps it alive (because the divCreator mouseout will fire) and when I mouseout of the popup it disappears.
这确保如果我将鼠标悬停在弹出窗口上,它会使其保持活动状态(因为 divCreator mouseout 会触发)并且当我将鼠标移出弹出窗口时它会消失。
However, with this method, whenever I mouseover a child element it detects a mouseout event from the parent element (divPopup) and closes the div.
但是,使用此方法,每当我将鼠标悬停在子元素上时,它都会检测到来自父元素 (divPopup) 的 mouseout 事件并关闭 div。
Can I make the children 'transparent' to Events, so-to-speak?
可以这么说,我可以让孩子们对事件“透明”吗?
回答by Gabriele Petrioli
There are two events that handle this case.
有两个事件可以处理这种情况。
The mouseenter
W3 DOM3 docsand mouseleave
W3 DOM3 docsbut they are currently in the DOM3 Events working draft.
在mouseenter
W3 DOM3文档和mouseleave
W3 DOM3文档,但他们目前都在DOM3事件工作草案。
They were introduced by Microsoft IE5.5, and Firefox has added support in v10.
它们是由 Microsoft IE5.5 引入的,Firefox 在 v10 中增加了支持。
A workaround is to manually check and cancel the execution of your handler if the newly moused-over element is a child of your top level one..
如果新鼠标悬停的元素是顶级元素的子元素,则解决方法是手动检查并取消处理程序的执行。
code adapted fromhttp://blog.stchur.com/2007/03/15/mouseenter-and-mouseleave-events-for-firefox-and-other-non-ie-browsers/
divCreator.addEventListener('mouseover', mouseEnter(createPopup), true);
divCreator.addEventListener('mouseout', mouseEnter(hidePopup), true);
function mouseEnter(_fn)
{
return function(_evt)
{
var relTarget = _evt.relatedTarget;
if (this === relTarget || isAChildOf(this, relTarget))
{ return; }
_fn.call(this, _evt);
}
};
function isAChildOf(_parent, _child)
{
if (_parent === _child) { return false; }
while (_child && _child !== _parent)
{ _child = _child.parentNode; }
return _child === _parent;
}
Demo athttp://jsfiddle.net/gaby/jMvHv/(open your console for log messages)
http://jsfiddle.net/gaby/jMvHv/ 上的演示(打开控制台查看日志消息)