JS中mouseenter触发但CSS动画仅执行一次问题求助
解决CSS Keyframes动画仅首次mouseenter触发的问题
问题原因
直接通过element.style.animation设置动画时,动画执行完毕后该属性仍保留在元素的行内样式中。再次触发mouseenter事件时,设置相同的动画属性值,浏览器会判定属性未发生变化,因此不会重新启动动画。
解决方案
方法一:重置行内动画属性后重新触发
每次触发事件时,先清除元素的动画属性,强制浏览器重绘后再重新设置动画:
const notes_animation = document.querySelectorAll(".note"); for (let i = 0; i < notes_animation.length; i++) { notes_animation[i].addEventListener('mouseenter', function() { const dot = this.querySelector(".backgr_color"); // 清除现有动画 dot.style.animation = 'none'; // 强制浏览器重绘,确保样式更新生效 void dot.offsetHeight; // 重新设置动画 dot.style.animation = "animate_notes 2500ms ease"; // 批量处理文本类元素 const animateTargets = [ this.querySelector(".note_text"), this.querySelector(".note_comment"), this.querySelector(".note_bottom") ]; animateTargets.forEach(el => { el.style.animation = 'none'; void el.offsetHeight; el.style.animation = "animate_text 2700ms ease"; }); }); }
方法二:使用CSS类控制动画(推荐)
将动画逻辑封装到CSS类中,通过添加/移除类来触发动画,同时配合animationend事件自动清理类:
- 首先定义CSS类:
.animate-notes { animation: animate_notes 2500ms ease; } .animate-text { animation: animate_text 2700ms ease; }
- 然后修改JavaScript代码:
const notes_animation = document.querySelectorAll(".note"); notes_animation.forEach(note => { note.addEventListener('mouseenter', function() { const dot = this.querySelector(".backgr_color"); // 先移除类,强制重绘后再添加 dot.classList.remove('animate-notes'); void dot.offsetHeight; dot.classList.add('animate-notes'); const textElements = [ this.querySelector(".note_text"), this.querySelector(".note_comment"), this.querySelector(".note_bottom") ]; textElements.forEach(el => { el.classList.remove('animate-text'); void el.offsetHeight; el.classList.add('animate-text'); }); }); // 监听动画结束事件,自动移除类避免冲突 const dot = note.querySelector(".backgr_color"); dot.addEventListener('animationend', () => dot.classList.remove('animate-notes')); note.querySelectorAll(".note_text, .note_comment, .note_bottom").forEach(el => { el.addEventListener('animationend', () => el.classList.remove('animate-text')); }); });
关键说明
void el.offsetHeight的作用是强制浏览器立即计算元素的布局信息,触发重绘。如果省略这一步,浏览器可能会把"移除属性/类 + 添加属性/类"的操作合并成一次,导致无法检测到样式变化,动画也就不会重新触发。
内容的提问来源于stack exchange,提问作者Eve Larson
相关产品推荐
相关产品推荐

