最近在做一个chatGpt聊天页面,需要把后端返回的文本以打字的效果输出。
一开始想着是利用CSS的动画效果来实现。实现方式如下:
<html> <head> <title>Typing</title> </head> <style> body { background: navajowhite; background-size: cover; font-family: 'Trebuchet MS', sans-serif; } .container { display: inline-block; } .content { overflow: hidden; border-right: .15em solid orange; white-space: nowrap; animation: typing 2s steps(20, end) forwards; font-size: 1.6rem; width: 0; } @keyframes typing { from { width: 0 } to { width: 100% } } </style> <body> <div class="container"> <div class="content">很明显,最初的打字机没有闪烁光标,但增加一个来模仿现代电脑/文字处理器闪烁光标的效果已经成为一种传统。闪烁的光标动画有助于使打印出来的文本从静态文本元素中脱颖而出</div> </div> </body> </html>
上面的代码可以实现单行文本不允许换行的前提下的打字效果。但是多行文本是不支持的,一旦允许换行,看到的效果真的是“惨不忍睹”。于是寻找其他的办法,利用JS来实现。最终也是采用了这个方法。
利用JS来实现的原理就是用JS截取字符串的方式。利用定时器每隔一定的时间一个一个字符的截取,然后拼装输出。这里特别提一下,定时器我这边是用的setTimeout来模拟setInteval效果来实现的,为什么要这样做,可以自行百度一下setInterval的缺点。
setTimeout模拟setInterval的代码如下:
let timer = null; function myInterval(fn, bool) { if (timer) { clearTimeout(timer); } if (bool) { return; } // timer = setTimeout(() => { const result = fn() myInterval(fn, result); }, 100) }
以上方法中增加了bool条件用来结束定时器,该值来源于回调函数fn的返回值。这么做的目的是想在需要截取的文字全部截图完之后,自动停止定时器,提高性能,节约资源。
接下来就是截取文字和如何输出,代码如下:
const content= document.getElementById('content'); const text= content.innerText; myInterval(() => { index++; content.innerText = text.substring(0, index++); if (index > text.length) { return true; } })
至此,文字输出为打字效果就完成了。完整代码如下:
<html> <head> <title>Typewriter effect</title> </head> <body> <div class="container"> <div id="content"> 正文: 亲爱的们,你们还在为周末的早餐去哪里吃而发愁吗?让我来为你们揭晓答案!那就是——“阳光下的蛋饼” Brunch店! 标签:index,const,打字,timer,content,fn,文本,模拟,myInterval From: https://www.cnblogs.com/brucefq/p/17671822.html