鼠标悬停和鼠标移出不触发动画元素

Mouseover and mouseout not firing with animating element

本文关键字:鼠标 动画 元素 悬停 移出      更新时间:2023-09-26

我需要检测用户是否悬停在一个元素上,这很简单。然而,当元素处于动画状态时,这些事件似乎不会触发。如果您检查我的小提琴,只需让元素动画经过您的鼠标而不移动鼠标,您将看到事件不会触发。为什么会发生这种情况是有道理的,但我还没有找到一个好的方法来获得我想要的行为,这是检测悬停,即使用户不移动他/她的鼠标和元素在它下面的动画。

任何想法吗?

谢谢!

注意:不使用外部库的解决方案是最佳的,但任何帮助仍然是感激的:)

HTML

<div id='moving'></div>
<ul id="message"></ul>
CSS

#moving {
  width: 50px;
  height: 50px;
  background-color: red;
  animation: move 7s linear;
}
@keyframes move {
    from {transform: translateX(0px)}
    to {transform: translateX(500px)}
}

JS

var counter = 0;
document.getElementById("moving").addEventListener("mouseover", function(){
    counter++;
    var node = document.createElement("LI");
    var textnode = document.createTextNode("Entered " + counter);
    node.appendChild(textnode);
    document.getElementById("message").appendChild(node);
});
document.getElementById("moving").addEventListener("mouseout", function(){
    var node = document.createElement("LI");
    var textnode = document.createTextNode("Left " + counter);
    node.appendChild(textnode);
    document.getElementById("message").appendChild(node);
});

这里是它的小提琴:https://jsfiddle.net/w5j842Lx/

您可以检查鼠标是否在间隔内进入或退出。这是一个从你的小提琴延伸出来的工作小提琴。

// This is the helper method I have written
var addMoveListener = function(element, onmouseover, onmouseout) {
  var over = false;
  var mouseX, mouseY;
  var checkOver = function(ev) {
    if (ev) {
      mouseX = ev.clientX;
      mouseY = ev.clientY;
    }
    if (mouseX == null || mouseY == null) return;
    var rect = element.getBoundingClientRect();
    var isInside = mouseX >= rect.left && mouseX < rect.right && mouseY >= rect.top && mouseY < rect.bottom;
    if (over && !isInside && onmouseout) onmouseout();
    if (!over && isInside && onmouseover) onmouseover();
    over = isInside;
  }
  document.addEventListener("mousemove", checkOver);
  var interval = setInterval(checkOver.bind(null, null), 100);
}
// Code below is for the sake of demonstration
var counter = 0;
var mouseovercallback = function() {
  counter++;
  console.log("Entered " + counter);
};
var mouseoutcallback = function() {
  console.log("Left " + counter);
};
addMoveListener(document.getElementById("moving"), mouseovercallback, mouseoutcallback);
#moving {
  width: 50px;
  height: 50px;
  background-color: red;
  animation: move 7s linear;
}
@keyframes move {
  from {
    transform: translateX(0px)
  }
  to {
    transform: translateX(500px)
  }
}
<div id='moving'></div>

代码每100毫秒检查一次鼠标是否被包含,以及鼠标是否被移动。如果您想处理元素不是矩形或旋转、倾斜等情况,则必须改进代码。

看看这个jsfiddle https://jsfiddle.net/3vpaoj59/它包含如下函数

  setInterval(checkMouse, 100);

基本上每秒调用函数10次,以检查鼠标的坐标是否在动画形状内。你的形状是正方形而不是圆形,所以你需要做一些不同的计算。这段代码很好,因为它没有使用插件,但它可能是CPU密集型的,在某些情况下可能会有较差的性能。