Jquery mouseenter () vs mouseover ()

因此,在阅读了最近回答 有个问题我不清楚,如果我真的了解之间的差异 mouseenter()mouseover()。邮政状态

鼠标悬停() :

在进入元素时和任何鼠标移动时都会触发 发生在元素内部。

鼠标输入() :

会在进入元素时开火。

我想出了一个 小提琴,使用两者,他们似乎是非常相似的。有人能给我解释一下这两者之间的区别吗?

我还尝试阅读了 JQuery 定义,它们说的是同一件事。

当鼠标指针进入元素时,mouseover 事件被发送到元素

当鼠标指针进入元素时,mouseenter 事件被发送到元素。

有人能举个例子说明一下吗?

118603 次浏览

查看 jquery 文档页面底部的示例代码和演示:

Http://api.jquery.com/mouseenter/

... 当指针移动到子元素时,鼠标悬停将触发 当鼠标输入器只在指针移动到 绑定元素。

当目标元素包含子元素时,可以看到下列行为:

Http://jsfiddle.net/zcwvj/7/

每次鼠标进入或离开子元素时,都会触发 mouseover,但不触发 mouseenter

$('#my_div').bind("mouseover mouseenter", function(e) {
var el = $("#" + e.type);
var n = +el.text();
el.text(++n);
});
#my_div {
padding: 0 20px 20px 0;
background-color: #eee;
margin-bottom: 10px;
width: 90px;
overflow: hidden;
}


#my_div>div {
float: left;
margin: 20px 0 0 20px;
height: 25px;
width: 25px;
background-color: #aaa;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>


<div>MouseEnter: <span id="mouseenter">0</span></div>
<div>MouseOver: <span id="mouseover">0</span></div>


<div id="my_div">
<div></div>
<div></div>
<div></div>
<div></div>
</div>

尽管它们以相同的方式运行,但是,mouseenter事件只有 当鼠标指针进入选定的元素时触发mouseover事件被触发 如果鼠标指针也进入任何子元素

鼠标输入器事件 不一样鼠标悬停处理 事件冒泡的方式。在 鼠标输入器事件中,只有 触发器是它的处理程序,当它绑定到 鼠标进入元素时,不是后代。 参考: < a href = “ https://api.jquery.com/mouseenter/”rel = “ nofollow”> https://api.jquery.com/mouseenter/

离开事件 不一样耗子处理 事件冒泡的方式。在 离开事件中,只有 触发器是它的处理程序,当它绑定到 鼠标离开元素时,不是后代。 参考: < a href = “ https://api.jquery.com/mouseleave/”rel = “ nofollow”> https://api.jquery.com/mouseleave/

这个例子展示了 鼠标移动鼠标输入器鼠标悬停事件之间的区别:

Https://jsfiddle.net/z8g613yd/

HTML:

<div onmousemove="myMoveFunction()">
<p>onmousemove: <br> <span id="demo">Mouse over me!</span></p>
</div>


<div onmouseenter="myEnterFunction()">
<p>onmouseenter: <br> <span id="demo2">Mouse over me!</span></p>
</div>


<div onmouseover="myOverFunction()">
<p>onmouseover: <br> <span id="demo3">Mouse over me!</span></p>
</div>

CSS:

div {
width: 200px;
height: 100px;
border: 1px solid black;
margin: 10px;
float: left;
padding: 30px;
text-align: center;
background-color: lightgray;
}


p {
background-color: white;
height: 50px;
}


p span {
background-color: #86fcd4;
padding: 0 20px;
}

约翰逊:

var x = 0;
var y = 0;
var z = 0;


function myMoveFunction() {
document.getElementById("demo").innerHTML = z += 1;
}


function myEnterFunction() {
document.getElementById("demo2").innerHTML = x += 1;
}


function myOverFunction() {
document.getElementById("demo3").innerHTML = y += 1;
}
  • onmousemove : 每次鼠标指针移动到 div 元素上时发生。
  • onmouseenter : 只有当鼠标指针进入 div 元素时才会发生。
  • onmouseover : 当鼠标指针进入 div 元素时发生, 及其子元素(p 和 span)。

旧的问题,但仍然没有良好的最新的答案与洞察力我。

由于 jQuery 在事件和处理程序 但它自己没有文件,但对这些不同的解释中使用了 Javascript 的措辞,让我首先从纯 Javascript 的角度阐明一下它们之间的区别:

  • 两个事件对
    • 当鼠标移动速度快于浏览器采样位置时,鼠标可以从外部/外部元素“跳转”到内部/最里面的元素
    • 任何 enter/over都会得到相应的 leave/out(可能是迟到/跳跃)
    • 事件转到指针下面的可见元素(不可见元素不能是目标)
    • 不冒泡 (事件对委托处理程序无用)
    • 事件注册本身定义了观察和抽象的区域
    • 在目标区域工作,就像一个带有池塘的公园: 池塘被认为是公园的一部分
    • 只要第一次输入/离开元素本身 或任何直系后代,就会在目标/区域上发出事件
    • 进入一个子代,从一个子代移动到另一个子代,或者回到目标并不能完成/重新启动 mouseenter/mouseleave循环(即没有事件触发)
    • 如果希望使用一个处理程序观察多个区域,请在每个区域/元素上注册它,或者使用下面讨论的其他事件对
    • 注册区域/元素的后代可以有自己的处理程序,创建一个具有独立 mouseenter/mouseleave事件周期的独立观测区域
    • 如果你考虑一下 mouseenter/mouseleave的冒泡版本会是什么样子,你最终会得到类似于 mouseover/mouseout的东西
    • 事件泡沫
    • 只要指针下面的元素发生更改,就会触发事件
      • 以前取样的元素上的 mouseout
      • 接着是新元素上的 mouseover
      • 事件不会“筑巢”: 例如,在孩子“过度”之前,父母会“出局”
    • target/relatedTarget表示新的和以前的元素
    • 如果你想观察不同的区域
      • 将一个处理程序注册到一个共同的父级(或多个父级,它们一起覆盖您想要监视的所有元素)上
      • 在处理程序元素和目标元素之间寻找您感兴趣的元素; 也许 $(event.target).closest(...)适合您的需要

不那么简单的 mouseover/mouseout例子:

$('.side-menu, .top-widget')
.on('mouseover mouseout', event => {
const target = event.type === 'mouseover' ? event.target : event.relatedTarget;
const thing = $(target).closest('[data-thing]').attr('data-thing') || 'default';
// do something with `thing`
});

现在,所有的浏览器都支持 mouseover/mouseoutmouseenter/mouseleave。尽管如此,jQuery 并没有将您的处理程序注册到 mouseenter/mouseleave,而是将它们放在 mouseover/mouseout周围的封装器上,因为下面的代码公开了它们。

模拟是不必要的,不完美的,并且浪费 CPU 周期: 它过滤掉了 mouseenter/mouseleave不会得到的 mouseover/mouseout事件,但是 target是混乱的。真正的 mouseenter/mouseleave将把处理程序元素作为目标,模拟可能指示该元素的子元素,即 mouseover/mouseout所携带的任何元素。

由于这个原因,我没有对这些事件使用 jQuery,但是举例来说:

$el[0].addEventListener('mouseover', e => ...);

const list = document.getElementById('log');
const outer = document.getElementById('outer');
const $outer = $(outer);


function log(tag, event) {
const li = list.insertBefore(document.createElement('li'), list.firstChild);
// only jQuery handlers have originalEvent
const e = event.originalEvent || event;
li.append(`${tag} got ${e.type} on ${e.target.id}`);
}


outer.addEventListener('mouseenter', log.bind(null, 'JSmouseenter'));
$outer.on('mouseenter', log.bind(null, '$mouseenter'));
div {
margin: 20px;
border: solid black 2px;
}


#inner {
min-height: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<body>
<div id=outer>
<ul id=log>
</ul>
</div>
</body>


注意: 对于委托处理程序,永远不要使用 jQuery 的“带有选择器注册的委托处理程序”。(另一个答案中的原因)使用以下(或类似) :

$(parent).on("mouseover", e => {
if ($(e.target).closest('.gold').length) {...};
});

而不是

$(parent).on("mouseover", '.gold', e => {...});