简体   繁体   English

从子元素输入父项时,不会触发MouseEnter事件

[英]MouseEnter event does not fire when entering parent from child element

I have HTML that looks like this: 我有看起来像这样的HTML:

<div id="parent">
  <div class="child">
    Child 1
  </div>
  <div class="child">
    Child 2
  </div>
  <div class="child">
    Child 3
  </div>
</div>

I attach mouseenter and mouseout events like so: 我将mouseenter和mouseout事件附加如下:

$("*").on("mouseenter", function() {
    $(this).addClass("mouse_over");
});

$("*").on("mouseout", function() {
    $(this).removeClass("mouse_over");
});

Now, imagine the following mouse sequence of events: 现在,想象一下以下鼠标事件序列:

  1. I move the mouse into the parent div. 我将鼠标移到父div中。 As expected the mouseenter event fires and the mouse_over class is put on the parent. 正如预期的那样,将触发mouseenter事件,并将mouse_over类放在父级上。
  2. I move into one of the children. 我搬进了其中一个孩子。 The mouseout event fires for the parent, and the mouseenter event fires for the child. mouseout事件为父级触发,mouseenter事件为子级触发。 Good. 好。
  3. I move the mouse back into the parent. 我将鼠标移回父级。 The mouseenter DOES NOT fire here. Mouseenter不会在此处触发。

The third step is the issue here. 第三步是这里的问题。 I want the mouse_over class to be put back on the parent when reentering the parent from its child element. 从子元素重新输入父级时,我希望将mouse_over类放回父级。

I think I understand why this is happening, as technically my mouse is in the parent the whole time so firing the mouseenter event does not make sense. 我想我理解为什么会这样,因为从技术上讲,我的鼠标一直都位于父级中,因此触发mouseenter事件没有任何意义。

Here's a fiddle better illustrating what I'm trying to do: 这是一个更好的说明,我正在尝试做的事情:

https://jsfiddle.net/tg1wg1xx/ https://jsfiddle.net/tg1wg1xx/

If you hover into the parent and children elements, you'll notice on your way out the pattern overlay is not placed on the parent. 如果将鼠标悬停在父元素和子元素上,则会注意到在样式叠加层未放置在父元素上的途中。

So how can I ensure that the overlay is always placed on whatever element I am currently hovering over? 那么,如何确保叠加层始终放置在我当前悬停的任何元素上?

As Boris explained in his answer , there's 2 different events. 鲍里斯(Boris)在回答中解释说 ,有2个不同的事件。 To quote him : 引用他:

  • mouseenter and mouseleave are triggered when you enter and leave a hierarchy of nodes, but not when you navigate that hierarchy's descendance. 当您进入和离开节点的层次结构时,会触发mouseentermouseleave ,但在导航该层次结构的后裔时不会触发。
  • mouseover and mouseout are triggered when the mouse respectively enters and leaves a node's "exclusive" space, so you get a "out" when the mouse gets into a child node. 当鼠标分别进入并离开节点的“独占”空间时,将触发mouseovermouseout ,因此,当鼠标进入子节点时,您将获得“ out”。

That being said, you need mouseover and mouseout since you need to trigger the mouse out when hovering a child. 话虽这么说,您需要mouseovermouseout ,因为你需要触发鼠标悬停出一个孩子的时候。

$("*").on("mouseover", function(e) {
    $(this).addClass("mouse_over");
});

$("*").on("mouseout", function(e) {
    $(this).removeClass("mouse_over");
});

Next, you need to know that event bubble in the tree. 接下来,您需要知道树中的事件气泡。 So when you mouseover on a child, the event is also propagated to the parents. 因此,当您将mouseover在孩子身上时,该事件也会传播给父母。 That's why the parent is in hover state even when hovering a child. 这就是为什么即使在悬停孩子时父母也处于悬停状态的原因。

To solve that, you need to use .stopPropagation() on the event object. 要解决此问题,您需要在事件对象上使用.stopPropagation()

$("*").on("mouseover", function(e) {
    $(this).addClass("mouse_over");
    e.stopPropagation();
});

$("*").on("mouseout", function(e) {
    $(this).removeClass("mouse_over");
    e.stopPropagation();
});

See it in action 实际观看


Bonus 奖金

In the spirit of writing less code, you can also use that : 本着减少编写代码的精神,您也可以使用以下代码:

$("*").on("mouseover mouseout", function(e) {
    $(this).toggleClass("mouse_over");
    e.stopPropagation();
});

mouse events in javascript can be disorienting. javascript中的鼠标事件可能会令人迷惑。 Please note that there are two pairs of events that don't mean the same thing : 请注意,有两对事件并不意味着同一件事:

  • mouseenter and mouseleave are triggered when you enter and leave a hierarchy of nodes, but not when you navigate that hierarchy's descendance. 当您进入和离开节点的层次结构时,会触发mouseentermouseleave ,但在导航该层次结构的后裔时不会触发。
  • mouseover and mouseout are triggered when the mouse respectively enters and leaves a node's "exclusive" space, so you get a "out" when the mouse gets into a child node. 当鼠标分别进入并离开节点的“独占”空间时,将触发mouseovermouseout ,因此,当鼠标进入子节点时,您将获得“ out”。

the behavior you are observing is because you are mixing the two : I updated your fiddle here https://jsfiddle.net/drxrea7e/1/ to use enter and leave. 您观察到的行为是因为您将两者混合在一起:我在这里更新了小提琴https://jsfiddle.net/drxrea7e/1/以使用enter和exit。

you can refer to the events' documentation on mozilla's site for detailed info. 您可以参考mozilla网站上的事件文档以获取详细信息。

Edit after your comment: ah then we need another thing : 编辑您的评论后:啊,我们还需要另外一件事:

the event actually bubbles, so the parent also receives it (but with target = theChild). 该事件实际上会冒泡,因此父级也会收到该事件(但target = theChild)。 So you want to add the class only if event.target == this :see my new version of the fiddle : https://jsfiddle.net/drxrea7e/3/ . 因此,仅在event.target == this时才添加类:请参阅我的小提琴的新版本: https : //jsfiddle.net/drxrea7e/3/

The children get the image from the class .mouse_over AND the red color from .parent, because background:url() overwrites background-color:white. 孩子们从类.mouse_over获取图像,从类.parent获取红色,因为background:url()覆盖了background-color:white。 Is that what you expected? 那是您所期望的吗?

Made some updates in your code to make it work as you wanted. 对您的代码进行了一些更新,以使其按需工作。

 $("*").on("mouseover", function(e) { $(this).addClass("mouse_over"); e.stopPropagation(); }); $("*").on("mouseout", function(e) { $(this).removeClass("mouse_over"); e.stopPropagation(); }); 
 #parent { padding: 24px; background-color:red; } .child { padding: 6px; background-color:white; } .mouse_over { background:url( data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAIUlEQVQYV2NkYGBIY2BgmMUABYxQGi4IEwCJgwWRBcCCAHscA2vMYjzKAAAAAElFTkSuQmCC ) repeat !important; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="parent"> <div class="child"> Child 1 </div> <div class="child"> Child 2 </div> <div class="child"> Child 3 </div> </div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 与后代选择器绑定时,为什么在子元素之前的父元素上触发事件? - Why does an event fire on a parent element before it's child when bound with a descendent selector? 从静止鼠标进入动画元素获取mouseenter事件 - getting a mouseenter event from a still mouse entering an animated element 为什么在SVG中输入/离开子元素时会触发mouseenter / mouseleave事件? - Why do the mouseenter/mouseleave events fire when entering/leaving child elements in an SVG? 当mouseenter在子元素上时如何不在父元素上触发mouseleave? - How to NOT trigger mouseleave on parent when mouseenter on child element? 如果在touchstart上删除了被触摸的子元素,则父元素的“ Touchend”事件不会触发 - 'Touchend' event of the parent do not fire if remove touched child element on touchstart 当 cursor 隐藏在其他 HTML 元素后面时,如何触发 mouseenter 事件? - How to fire mouseenter event when cursor is hidden behind other HTML element? 事件不会从子元素冒泡到父元素 - Event not Bubbling to Parent Element from Child Element 如何从子组件触发事件到父组件? - How fire an event from child component to parent component? 如果父级有边框,当鼠标退出父级和子级时,如何避免来自父级元素的mouseover事件 - How to avoid the mouseover event from the parent element when the mouse is exiting both parent and child if the parent has a border mouseenter在父级上时如何显示元素? - How to show element when mouseenter on parent?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM