首页 > 解决方案 > 即使鼠标移出,Mouseenter 事件也会触发两次

问题描述

当页面加载时以及在 div 上发生 mouseenter 事件时,我正在向 div 添加两个摇动动画

我有一个耻辱动画,我想在页面加载时播放不同名称的shake1 和shake2,并在div 悬停时再次播放。下面是html、css和js的样子

let $image = document.querySelector("div");
$image.addEventListener("mouseenter", function() {
  $image.style.animationPlayState = "running";
});
div {
  background: red;
  animation-name: shake1;
  animation-duration: .5s;
}

@keyframes shake1 {
  0% {
    transform: translate(1px, 1px) rotate(0deg);
  }
  10% {
    transform: translate(-1px, -2px) rotate(-1deg);
  }
  20% {
    transform: translate(-3px, 0px) rotate(1deg);
  }
  30% {
    transform: translate(3px, 2px) rotate(0deg);
  }
  40% {
    transform: translate(1px, -1px) rotate(1deg);
  }
  50% {
    transform: translate(-1px, 2px) rotate(-1deg);
  }
  60% {
    transform: translate(-3px, 1px) rotate(0deg);
  }
  70% {
    transform: translate(3px, 1px) rotate(-1deg);
  }
  80% {
    transform: translate(-1px, -1px) rotate(1deg);
  }
  90% {
    transform: translate(1px, 2px) rotate(0deg);
  }
  100% {
    transform: translate(1px, -2px) rotate(-1deg);
  }
}

div:hover {
  animation-name: shake2;
  animation-duration: .5s;
}

@keyframes shake2 {
  0% {
    transform: translate(1px, 1px) rotate(0deg);
  }
  10% {
    transform: translate(-1px, -2px) rotate(-1deg);
  }
  20% {
    transform: translate(-3px, 0px) rotate(1deg);
  }
  30% {
    transform: translate(3px, 2px) rotate(0deg);
  }
  40% {
    transform: translate(1px, -1px) rotate(1deg);
  }
  50% {
    transform: translate(-1px, 2px) rotate(-1deg);
  }
  60% {
    transform: translate(-3px, 1px) rotate(0deg);
  }
  70% {
    transform: translate(3px, 1px) rotate(-1deg);
  }
  80% {
    transform: translate(-1px, -1px) rotate(1deg);
  }
  90% {
    transform: translate(1px, 2px) rotate(0deg);
  }
  100% {
    transform: translate(1px, -2px) rotate(-1deg);
  }
}
<div style="width:100px; height: 100px;">
</div>

我希望摇动动画在页面加载时起作用,并在 div 悬停时再次起作用。但是它在页面加载时播放,并且在 div 上发生 mouseenter 事件时播放,并且在鼠标离开 div 时也播放。我认为当鼠标离开 div 时正在播放加载动画,就好像页面已加载一样。我如何让它按预期工作

标签: javascripthtmlcssmouseeventaddeventlistener

解决方案


我认为这种行为是由于您在目标元素上定义了两个不同的动画,因此当您将 animationPlayState 设置为“正在运行”时,它会触发这两个动画。

我已更新您的代码以记录当前动画名称:

let $image = document.querySelector(".shake");

$image.addEventListener("animationstart", function(event) {
  console.log(event.animationName);
})

$image.addEventListener("mouseenter", function(event) {
  $image.style.animationPlayState = "running";
});
div.shake {
  background: red;
  animation-name: shake1;
  animation-duration: .5s;
}

@keyframes shake1 {
  0% {
    transform: translate(1px, 1px) rotate(0deg);
  }
  10% {
    transform: translate(-1px, -2px) rotate(-1deg);
  }
  20% {
    transform: translate(-3px, 0px) rotate(1deg);
  }
  30% {
    transform: translate(3px, 2px) rotate(0deg);
  }
  40% {
    transform: translate(1px, -1px) rotate(1deg);
  }
  50% {
    transform: translate(-1px, 2px) rotate(-1deg);
  }
  60% {
    transform: translate(-3px, 1px) rotate(0deg);
  }
  70% {
    transform: translate(3px, 1px) rotate(-1deg);
  }
  80% {
    transform: translate(-1px, -1px) rotate(1deg);
  }
  90% {
    transform: translate(1px, 2px) rotate(0deg);
  }
  100% {
    transform: translate(1px, -2px) rotate(-1deg);
  }
}

div.shake:hover {
  animation-name: shake2;
  animation-duration: .5s;
}

@keyframes shake2 {
  0% {
    transform: translate(1px, 1px) rotate(0deg);
  }
  10% {
    transform: translate(-1px, -2px) rotate(-1deg);
  }
  20% {
    transform: translate(-3px, 0px) rotate(1deg);
  }
  30% {
    transform: translate(3px, 2px) rotate(0deg);
  }
  40% {
    transform: translate(1px, -1px) rotate(1deg);
  }
  50% {
    transform: translate(-1px, 2px) rotate(-1deg);
  }
  60% {
    transform: translate(-3px, 1px) rotate(0deg);
  }
  70% {
    transform: translate(3px, 1px) rotate(-1deg);
  }
  80% {
    transform: translate(-1px, -1px) rotate(1deg);
  }
  90% {
    transform: translate(1px, 2px) rotate(0deg);
  }
  100% {
    transform: translate(1px, -2px) rotate(-1deg);
  }
}
<div class="shake" style="width:100px; height: 100px;">
</div>

作为一种解决方法,您可以在 mouseleave 上将 animationPlayState 设置为“暂停”:

let $image = document.querySelector("div");
$image.addEventListener("mouseenter", function() {
  $image.style.animationPlayState = "running";
});

$image.addEventListener("mouseleave", function() {
  $image.style.animationPlayState = "paused";
});
div {
  background: red;
  animation-name: shake1;
  animation-duration: .5s;
}

@keyframes shake1 {
  0% {
    transform: translate(1px, 1px) rotate(0deg);
  }
  10% {
    transform: translate(-1px, -2px) rotate(-1deg);
  }
  20% {
    transform: translate(-3px, 0px) rotate(1deg);
  }
  30% {
    transform: translate(3px, 2px) rotate(0deg);
  }
  40% {
    transform: translate(1px, -1px) rotate(1deg);
  }
  50% {
    transform: translate(-1px, 2px) rotate(-1deg);
  }
  60% {
    transform: translate(-3px, 1px) rotate(0deg);
  }
  70% {
    transform: translate(3px, 1px) rotate(-1deg);
  }
  80% {
    transform: translate(-1px, -1px) rotate(1deg);
  }
  90% {
    transform: translate(1px, 2px) rotate(0deg);
  }
  100% {
    transform: translate(1px, -2px) rotate(-1deg);
  }
}

div:hover {
  animation-name: shake2;
  animation-duration: .5s;
}

@keyframes shake2 {
  0% {
    transform: translate(1px, 1px) rotate(0deg);
  }
  10% {
    transform: translate(-1px, -2px) rotate(-1deg);
  }
  20% {
    transform: translate(-3px, 0px) rotate(1deg);
  }
  30% {
    transform: translate(3px, 2px) rotate(0deg);
  }
  40% {
    transform: translate(1px, -1px) rotate(1deg);
  }
  50% {
    transform: translate(-1px, 2px) rotate(-1deg);
  }
  60% {
    transform: translate(-3px, 1px) rotate(0deg);
  }
  70% {
    transform: translate(3px, 1px) rotate(-1deg);
  }
  80% {
    transform: translate(-1px, -1px) rotate(1deg);
  }
  90% {
    transform: translate(1px, 2px) rotate(0deg);
  }
  100% {
    transform: translate(1px, -2px) rotate(-1deg);
  }
}
<div style="width:100px; height: 100px;">
</div>


推荐阅读