jQuery mouseenter() 与 mouseover()
Posted
技术标签:
【中文标题】jQuery mouseenter() 与 mouseover()【英文标题】:Jquery mouseenter() vs mouseover() 【发布时间】:2011-11-09 08:02:01 【问题描述】:所以在阅读了最近回答的question 之后,我不清楚我是否真的理解mouseenter()
和mouseover()
之间的区别。帖子说
MouseOver():
将在进入元素时以及任何鼠标移动时触发 发生在元素内。
MouseEnter():
在输入元素时触发。
我想出了一个使用两者的fiddle,它们似乎非常相似。谁能给我解释一下这两者的区别?
我也尝试过阅读 JQuery 定义,两者都说同样的话。
当鼠标指针进入元素时,鼠标悬停事件被发送到元素
当鼠标指针进入元素时,mouseenter 事件被发送到元素。
有人可以举例说明一下吗?
【问题讨论】:
documentation 中的演示很好地展示了 imo。 值得注意的是,mouseenter 和 mouseleave 仅在 IE 中是专有事件,并由 jQuery 在其他浏览器中模拟(它们现在似乎在规范中,但尚未在其他浏览器中实现。参见 quirksmode.org/dom/events/mouseover.html) What is the difference between the mouseover and mouseenter events?的可能重复 【参考方案1】:查看jquery文档页面底部的示例代码和演示:
http://api.jquery.com/mouseenter/
...当指针移入子元素时触发鼠标悬停 好吧,而 mouseenter 仅在指针移入时触发 绑定元素。
【讨论】:
【参考方案2】:当您的目标元素包含子元素时,您会看到该行为:
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>
【讨论】:
@psychobrm - 不。玩这两个也跟踪mouseleave
事件的演示:jsfiddle.net/ZCWvJ/232jsfiddle.net/ZCWvJ/233 如果在与进入+离开相同的地方,那么结束的计数将是进入和离开的计数总和。
写var n = + el.text();
而不是var n = el.text();
有什么具体原因吗?我只是出于好奇。
@FredrickGauss - 我正在使用+
运算符将el.text()
返回的字符串强制转换为数字。我需要吗?不会。在这种情况下,使用n
的下一条语句也会将其强制转换为数字。那么,为什么我使用它?我不确定……这是两年前的事了。这是一个好习惯。它使我的意图明确。可能我在保存之前最初有n + 1
,但决定将我的代码缩小2个字符并只使用++n
。 n + 1
不会将n
强制转换为一个数字,而是将1
强制转换为一个字符串,从而导致输出,例如0111111
。
@gilly3 - 感谢您详细解释您在脑海中的旅行。
@gilly3 很好的总结,但有一个小的改进:“或者离开一个子元素”应该是“或者离开一个子元素,因为子元素和父元素之间存在差距。你的小提琴有一个边距/内边距,因此当您离开子元素时,您确实会收到鼠标悬停事件,但尝试不使用内边距/边距时,您将不会收到此事件。【参考方案3】:
尽管它们的操作方式相同,但mouseenter
事件仅在鼠标指针进入所选元素时触发。 如果鼠标指针也进入任何子元素,则会触发mouseover
事件。
【讨论】:
【参考方案4】:mouseenter 事件在处理事件冒泡 的方式上不同于 mouseover。 mouseenter 事件,仅在 鼠标进入其绑定的元素时触发其处理程序,不是后代 . 参考:https://api.jquery.com/mouseenter/
mouseleave 事件不同于 mouseout 处理事件冒泡 的方式。 mouseleave 事件,仅在 鼠标离开它所绑定的元素时触发其处理程序,不是后代 . 参考:https://api.jquery.com/mouseleave/
【讨论】:
【参考方案5】:此示例演示了 mousemove、mouseenter 和 mouseover 事件之间的区别:
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;
JS:
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)。
【讨论】:
jsfiddle 不知何故坏了,说功能未定义 - 我只是将所有 js 分叉并移动到<script>
jsfiddle.net/orc8empd【参考方案6】:
老问题,但在 imo 洞察力中仍然没有很好的最新答案。
由于 jQuery 对事件和处理程序使用 javascript 措辞,但对这些事件和处理程序有自己的未记录但不同的解释,让我首先阐明与纯 Javascript 观点的区别:
两个事件对 当移动速度快于浏览器对其位置的采样速度时,鼠标可以从外部/外部元素“跳转”到内部/最内部元素 任何enter/over
都会获得相应的leave/out
(可能迟到/跳跃)
事件转到指针下方的可见元素(不可见元素不能成为目标)
mouseenter/mouseleave
不会冒泡(事件对委托处理程序无用)
事件注册本身定义了观察和抽象的区域
在目标区域工作,就像一个带池塘的公园:池塘被认为是公园的一部分
每当元素本身或任何直接的后代第一次进入/离开时,都会在目标/区域上发出事件
进入后代、从一个后代移动到另一个后代或返回目标不会完成/重新启动 mouseenter/mouseleave
循环(即没有触发事件)
如果您想使用一个处理程序观察多个区域,请在每个区域/元素上注册它或使用接下来讨论的另一个事件对
注册区域/元素的后代可以有自己的处理程序,创建一个独立的观察区域,具有独立的mouseenter/mouseleave
事件周期
如果你想一下mouseenter/mouseleave
的冒泡版本会是什么样子,你最终会得到类似mouseover/mouseout
的东西
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/mouseout
和mouseenter/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 的“带有选择器注册的委托处理程序”。 (原因在another answer。)使用这个(或类似的):
$(parent).on("mouseover", e =>
if ($(e.target).closest('.gold').length) ...;
);
而不是
$(parent).on("mouseover", '.gold', e => ...);
【讨论】:
以上是关于jQuery mouseenter() 与 mouseover()的主要内容,如果未能解决你的问题,请参考以下文章
jQuery mouseover与mouseenter,mouseout与mouseleave的区别
Jquery hover方法使用及 mouseenter与mouseleave和 mouseover与mouseout的区别