当鼠标在子元素之间移动时,如何不被鼠标悬停/鼠标悬停事件发送垃圾邮件?

时间:2018-07-30 22:48:45

标签: javascript

最佳示例说明:

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>

请注意,当您将鼠标移到蓝色边框上而仍然停留在红色边框内时,它将被不必要的鼠标移出/鼠标移开事件所淹没。

在我的情况下,这很昂贵,在我的网页中,我的元素彼此上下5层层叠在一起,因此垃圾邮件变得更糟。每次将鼠标悬停/鼠标移出都会触发很多其他事情,如果在一毫秒内发生10倍,就会使事情变得结结巴巴。

我不想禁用html层次结构中传递的事件(如#b在#a中触发鼠标事件),这是理想的,因为我在页面上监视的内容也具有怪异的形状。

如果鼠标没有真正离开受监视元素及其子元素的限制,是否有办法不会被鼠标移出/鼠标悬停?

或者,有没有一种方法可以在处理当前(mouseout)事件时检测到另一个事件(随后的鼠标悬停)正在发生?

当前,我每次触发事件时都会设置一个变量,然后一个1ms的超时循环会检查该变量,然后触发需要在鼠标悬停/鼠标上进行的其他操作,但我不喜欢它。

1 个答案:

答案 0 :(得分:2)

您想要mouseentermouseleave事件,而不是mouseovermouseout

当任何子元素获得或丢失鼠标时,会触发

mouseovermouseout事件。 mouseentermouseleave事件仅在首次输入或完全离开该事件的元素时触发。

Here's some more info上的区别

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>