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

时间:2017-01-19 15:16:34

标签: javascript jquery html events dom-events

我的HTML看起来像这样:

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

我附上了mouseenter和mouseout事件,如下所示:

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

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

现在,想象一下以下鼠标事件序列:

  1. 我将鼠标移动到父div中。正如预期的那样,将触发mouseenter事件,并将mouse_over类放在父级上。
  2. 我搬进了其中一个孩子。将为父项触发mouseout事件,并为该子项触发mouseenter事件。好。
  3. 我将鼠标移回父母。 mouseenter不会在这里开火。
  4. 第三步是这里的问题。我希望在从子元素重新输入父元素时将mouse_over类放回到父元素上。

    我想我明白为什么会发生这种情况,因为技术上我的鼠标一直在父母身上,因此触发mouseenter事件是没有意义的。

    这里有一个更好的说明我想要做的事情:

    https://jsfiddle.net/tg1wg1xx/

    如果您将鼠标悬停在父元素和子元素中,您在出路时会注意到图案叠加层未放置在父元素上。

    那么我怎样才能确保叠加始终放在我当前悬停的任何元素上?

3 个答案:

答案 0 :(得分:3)

作为Boris explained in his answer,有2个不同的事件。引用他:

  
      当您进入和离开节点层次结构时会触发
  • mouseentermouseleave,但是当您导航该层次结构的下降时则不会触发。
  •   
  • mouseovermouseout在鼠标分别进入和离开节点时被触发&#34;排除&#34;空间,所以你得到一个&#34; out&#34;当鼠标进入子节点时。
  •   

话虽如此,您需要mouseovermouseout,因为您需要在将孩子悬停时触发鼠标。

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

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

接下来,您需要知道树中的事件气泡。因此,当您对孩子mouseover时,该事件也会传播给父母。这就是为什么父母即使在徘徊孩子时也处于悬停状态。

要解决此问题,您需要在事件对象上使用.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

加成

本着写少量代码的精神,您也可以使用:

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

答案 1 :(得分:2)

javascript中的鼠标事件可能令人迷惑。请注意,有两对事件并不意味着相同的事情:

    当您进入和离开节点层次结构时会触发
  • $ adb install -g <package>.apk mouseenter,但是当您导航该层次结构的下降时则不会触发。
  • mouseleavemouseover在鼠标分别进入和离开节点时被触发&#34;排除&#34;空间,所以你得到一个&#34; out&#34;当鼠标进入子节点时

你正在观察的行为是因为你混合了两个:我在这里更新你的小提琴https://jsfiddle.net/drxrea7e/1/以使用进入和离开。

你可以参考活动&#39; documentation on mozilla's site了解详细信息。

评论后编辑:啊,那我们需要另一件事:

事件实际上是气泡,所以父母也接收它(但是目标= theChild)。所以你只想在event.target ==这个时添加这个类:看看我的新版小提琴:https://jsfiddle.net/drxrea7e/3/

孩子们从.mouse_over类中获取图像,从.parent获取红色,因为background:url()会覆盖background-color:white。这是你所期望的吗?

答案 2 :(得分:2)

在您的代码中进行了一些更新,以使其按您的需要运行。

$("*").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>