首页 文章

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

提问于
浏览
1

我有这样的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");
});

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

  • 我将鼠标移动到父div中 . 正如预期的那样,mouseenter事件将触发,mouse_over类将放在父级上 .

  • 我搬进了其中一个孩子 . 将为父项触发mouseout事件,并为该子项触发mouseenter事件 . 好 .

  • 我将鼠标移回父母 . mouseenter不会在这里开火 .

第三步是这里的问题 . 我希望在从子元素重新输入父元素时将mouse_over类放回到父元素上 .

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

这是一个更好的说明我正在尝试做的事情:

https://jsfiddle.net/tg1wg1xx/

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

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

3 回答

  • 3

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

    当您进入和离开节点层次结构时会触发mouseenter和mouseleave,但在导航该层次结构的下降时则不会触发 . 鼠标分别进入和离开节点的“独占”空间时会触发mouseover和mouseout,因此当鼠标进入子节点时会出现“out” .

    话虽这么说,你需要 mouseovermouseout 因为你需要在悬停孩子时触发鼠标 .

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

    接下来,您需要知道树中的事件气泡 . 所以当你对孩子说话时,这个事件也会传播给父母 . 这就是为什么父母即使在徘徊一个孩子时也处于悬停状态 .

    要解决此问题,您需要在事件对象上使用 .stopPropagation() .

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

    看到它在行动


    奖金

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

    $("*").on("mouseover mouseout", function(e) {
        $(this).toggleClass("mouse_over");
        e.stopPropagation();
    });
    
  • 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>
    
  • 2

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

    当您进入和离开节点层次结构时会触发

    • mouseentermouseleave ,但在导航该层次结构的下降时则不会触发 .
      当鼠标分别进入和离开节点的"exclusive"空间时会触发
    • mouseovermouseout ,因此当鼠标进入子节点时会得到"out" .

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

    有关详细信息,请参阅事件'documentation on mozilla's site .

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

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

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

相关问题