如何让文字动画在页面加载时仅触发一次(替代onmouseover)
问题:将鼠标触发的文字动画改为页面加载时自动执行一次
我在个人网站上使用了从Codepen获取的原生HTML文字动画效果,现在想把原本通过onmouseover触发的动画,修改为页面加载时仅执行一次。尝试修改事件(比如用onLoad)及其他写法后均未生效,寻求解决方法。
原代码
<script> const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let interval = null; document.querySelector("h2").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); } </script>
尝试的代码1
<script> const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let interval = null; document.querySelector("h2").onLoad = 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); } </script>
尝试的代码2
document.querySelector("h2") = function(){<script> const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let interval = null; document.querySelector("h2").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); } </script>};
解决方案
问题原因
- 尝试1中,
onLoad是window对象的事件,不能直接绑定在h2元素上,元素本身没有这个事件,所以不会触发。 - 尝试2的写法存在语法错误,不能直接把函数赋值给
document.querySelector("h2"),也不能在函数内部嵌套<script>标签。
正确代码实现
把动画逻辑封装成独立函数,通过页面加载事件触发,确保DOM渲染完成后执行:
<script> const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let interval = null; // 获取目标h2元素 const targetHeading = document.querySelector("h2"); // 封装文字动画函数 function startTextAnimation(element) { let iteration = 0; clearInterval(interval); interval = setInterval(() => { element.innerText = element.innerText .split("") .map((letter, index) => { if(index < iteration) { return element.dataset.value[index]; } return letters[Math.floor(Math.random() * 26)] }) .join(""); if(iteration >= element.dataset.value.length){ clearInterval(interval); } iteration += 1 / 3; }, 30); } // 页面DOM加载完成后执行动画 document.addEventListener('DOMContentLoaded', () => { startTextAnimation(targetHeading); }); </script>
替代方案(更简单)
如果把这段脚本放在HTML的</body>标签之前,此时DOM已经加载完成,可以直接调用函数,无需监听事件:
<script> const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let interval = null; const targetHeading = document.querySelector("h2"); function startTextAnimation(element) { let iteration = 0; clearInterval(interval); interval = setInterval(() => { element.innerText = element.innerText .split("") .map((letter, index) => { if(index < iteration) { return element.dataset.value[index]; } return letters[Math.floor(Math.random() * 26)] }) .join(""); if(iteration >= element.dataset.value.length){ clearInterval(interval); } iteration += 1 / 3; }, 30); } // 直接执行动画 startTextAnimation(targetHeading); </script>
内容的提问来源于stack exchange,提问作者Didier Marin
相关产品推荐
相关产品推荐

