javascript - 当鼠标在子元素之间移动时,如何不被 mouseover/mouseout 事件发送垃圾邮件?
问题描述
最好用一个例子来解释:
var root = document.querySelector("#a");
var msg_stack = document.querySelector("#msg_stack");
var last_msg = document.querySelector("#dummy");
function pad(v) {
v = "" + v;
while (v.length < 3) v = "0" + v;
return v;
}
function hover(v) {
var msg = document.createElement("div");
msg.innerText = pad(msg_stack.children.length) + ": " + v;
last_msg = msg_stack.insertBefore(msg, last_msg);
}
root.addEventListener("mouseover", function() { hover(true); });
root.addEventListener("mouseout", function() { hover(false); });
#a {
position:absolute;
left:10px;top:10px;width:200px;height:50px;
background-color:red;
}
#b {
position:absolute;
right:0px;top:0px;width:50px;height:200px;
background-color:red;
}
#b:after {
content:"";
position:absolute;
left:0;top:0;height:50px;
border-left:solid 1px blue;
}
#msg_stack {
position:absolute;
left:230px;top:10px;width:500px;height:200px;
}
<div id="a"><div id="b"></div></div>
<div id="msg_stack"><div id="dummy"></div></div>
请注意,当您将鼠标移到蓝色边框上同时仍停留在红色边框内时,它会被不必要的 mouseout/mouseover 事件发送垃圾邮件。
就我而言,这很昂贵,在我的网页中,我的元素彼此叠加了 5 层,因此垃圾邮件更加严重。每次鼠标悬停/鼠标移出都会触发一堆其他事情,如果这种情况在一毫秒内发生 10 倍,它会让事情变得卡顿。
我不想禁用向上传递 html 层次结构的事件(如在 #a 中触发鼠标事件的 #b 中),这是可取的,因为我在页面上监控的东西也有奇怪的形状。
如果鼠标没有真正离开受监视元素及其子元素的范围,有没有办法不被 mouseout/mouseover 发送垃圾邮件?
或者,有没有办法在处理当前(鼠标悬停)事件时检测到另一个事件(随后的鼠标悬停)正在从管道中下来?
目前我在每次触发事件时设置一个变量,然后一个 1ms 超时循环检查该变量,然后触发需要在 mouseover/mouseut 上发生的其他操作,但我不喜欢它。
解决方案
您想要mouseenter
andmouseleave
事件而不是mouseover
and mouseout
。
mouseover
并且mouseout
当任何子元素获得或失去鼠标时触发事件。mouseenter
并且mouseleave
事件仅在处理事件的元素第一次进入或完全离开时触发。
这是有关差异的更多信息
var root = document.querySelector("#a");
var msg_stack = document.querySelector("#msg_stack");
var last_msg = document.querySelector("#dummy");
function pad(v) {
v = "" + v;
while (v.length < 3) v = "0" + v;
return v;
}
function hover(v) {
var msg = document.createElement("div");
msg.innerText = pad(msg_stack.children.length) + ": " + v;
last_msg = msg_stack.insertBefore(msg, last_msg);
}
root.addEventListener("mouseenter", function() { hover(true); });
root.addEventListener("mouseleave", function() { hover(false); });
#a {
position:absolute;
left:10px;top:10px;width:200px;height:50px;
background-color:red;
}
#b {
position:absolute;
right:0px;top:0px;width:50px;height:200px;
background-color:red;
}
#b:after {
content:"";
position:absolute;
left:0;top:0;height:50px;
border-left:solid 1px blue;
}
#msg_stack {
position:absolute;
left:230px;top:10px;width:500px;height:200px;
}
<div id="a"><div id="b"></div></div>
<div id="msg_stack"><div id="dummy"></div></div>
推荐阅读
- django - 从购物车中删除按钮在 django 中不起作用?
- ios - 返回屏幕后释放 UITableViewCell 的高亮状态
- azure - PowerBI MicrosoftAzureConsumptionInsights - 更改查询以获得超过 2 个月
- c++ - macOS Catalina 录屏权限
- java - JPA Postgres - 无法将动态 JSON 转换为 Java 类型
- matlab - 在 uitab 上创建具有多个轴的图。在 Matlab 中使用 addaxis
- java - Java 8:如何检查对象的所有字段是否为 NULL,除了一个
- user-interface - 我想从剪贴板复制、粘贴和剪切 CEdit 中的内容
- powershell-3.0 - 在 power-shell 工作流中使用 CSV 导入
- reactjs - 如何从客户端在 S3 中上传大型媒体文件?