原生JavaScript实现的<li>元素鼠标悬停效果异常问题求助
鼠标悬停文字动画首次触发异常问题
我用JavaScript给三个<li>元素做鼠标悬停的字符切换动画,但首次触发时效果异常,必须反复悬停才能恢复原本的文本。
效果说明
- 原文本:三个列表项分别显示
// ABOUT、// PROJECTS、// CONTACT - 首次悬停异常:动画结束后文本无法正确恢复,出现错乱
- 正常效果(反复悬停后):鼠标悬停时字符逐个随机切换,最终恢复为原文本
HTML代码
<ul> <li data-value="// ABOUT" ><a href="#" >// ABOUT </a></li> <li data-value="// PROJECTS" ><a href='#' >// PROJECTS </a></li> <li data-value="// CONTACT" ><a href="#" >// CONTACT </a></li> </ul>
原JavaScript代码
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let interval = null; document.querySelectorAll("li").forEach(li => { li.onmouseover = event => { let iteration = 0; clearInterval(interval); interval = setInterval(() => { event.target.innerText = event.target.innerText .split("") .map((letter, index) => { if (index < iteration) { return event.target.dataset.value[index]; } return letters[Math.floor(Math.random() * 26)]; }) .join(""); if (iteration >= event.target.dataset.value.length) { clearInterval(interval); } iteration += 1 / 3; }, 30); }; });
问题原因
- 事件目标指向错误:
event.target实际指向的是<li>内部的<a>标签,但data-value属性是绑定在<li>上的,首次获取dataset.value会失败,导致文本错乱。 - 共享定时器冲突:所有
<li>共用同一个全局interval变量,快速切换悬停目标时,定时器会被意外清除,导致动画中断或状态异常。 - 文本基准逻辑错误:动画中用
event.target.innerText作为修改基准,首次操作时该文本是<a>的原始内容,后续修改后基准发生变化,导致反复悬停后看似正常但逻辑存在隐患。
修复后的代码
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; document.querySelectorAll("li").forEach(li => { // 每个li单独维护定时器,避免元素间干扰 let liInterval = null; // 提前缓存目标文本,避免重复读取DOM属性 const targetText = li.dataset.value.trim(); li.addEventListener('mouseover', () => { let iteration = 0; const aTag = li.querySelector('a'); clearInterval(liInterval); liInterval = setInterval(() => { aTag.innerText = targetText .split("") .map((letter, index) => { if (index < iteration) { return targetText[index]; } return letters[Math.floor(Math.random() * 26)]; }) .join(""); if (iteration >= targetText.length) { clearInterval(liInterval); } iteration += 1 / 3; }, 30); }); // 鼠标离开时直接恢复原文本,优化体验 li.addEventListener('mouseout', () => { clearInterval(liInterval); li.querySelector('a').innerText = targetText; }); });
修复点说明
- 给每个
<li>分配独立的定时器变量,彻底解决多元素间的定时器冲突问题。 - 提前缓存
data-value的目标文本,明确操作<li>内部的<a>标签,避免event.target指向错误的问题。 - 增加
mouseout事件监听,鼠标离开时立即恢复原文本,避免残留动画状态影响后续操作。
内容的提问来源于stack exchange,提问作者c0d3rl0l
相关产品推荐
相关产品推荐

