单行循环打字机特效
一个轻量的单行循环打字机效果,不用依赖任何框架或插件,几行原生 CSS + JS 就能搞定。这个特效的核心是模拟打字机的“逐字输入→停顿→逐字删除→切换文案”流程,很适合嵌入网页。
一、核心原理拆解
打字机特效的实现逻辑其实很简单,主要分为三个步骤:
- 逐字打印:遍历文案字符串,逐个字符插入到页面中,配合时间延迟模拟打字速度。
- 停顿删除:文案打印完成后,停顿一段时间供用户阅读,再从后往前逐个删除字符。
- 循环切换:删除完成后,切换到下一条文案,重复上述流程,实现无限轮播。
另外,搭配等宽字体和闪烁光标,能让特效的还原度和视觉效果大大提升。
二、代码实现
直接上代码,复制到 HTML 就能运行,关键部分都加了详细注释。
CSS部分
<style>
body{background:#fff;color:#000;font:20px/1.6 'Courier New',monospace;padding:40px;}
/* 光标闪烁 */
.cursor{display:inline-block;width:2px;height:1em;background:#000;vertical-align:text-bottom;animation:blink .9s steps(1) infinite;}
@keyframes blink{50%{opacity:0;}}
</style>body主体
<div id="typer"></div>JS实现
<script>
/* =========================
* 可配置区域:文案 & 速度
* ========================= */
const lines = [
'第一行文案,打完就删。',
'第二行文案,删完换下一行。',
'第三行文案,循环往复。'
];
const typeSpeed = 120; // 打字间隔
const delSpeed = 120; // 删除间隔
const holdDelay = 800; // 打完后的停顿
const box = document.getElementById('typer');
let idx = 0;
/* 简易 sleep 工具函数 */
async function sleep(ms){ return new Promise(r=>setTimeout(r,ms)); }
/* 逐字打印一行文字,光标跟随 */
async function type(text){
const cursor = document.createElement('span');
cursor.className = 'cursor';
box.appendChild(cursor);
for(const ch of text){
cursor.insertAdjacentText('beforebegin', ch);
await sleep(typeSpeed);
}
}
/* 反向删完整行 */
async function del(){
const cursor = box.querySelector('.cursor');
while(cursor.previousSibling){
cursor.previousSibling.remove();
await sleep(delSpeed);
}
cursor.remove();
}
/* 主循环:打 → 停 → 删 → 换行 → 循环 */
async function loop(){
while(true){
await type(lines[idx]);
await sleep(holdDelay);
await del();
await sleep(500)
idx = (idx + 1) % lines.length;
}
}
loop();
</script>三、关键代码详解
1. 样式部分
- 等宽字体:选用
Courier New这种等宽字体,每个字符宽度一致,打字时的视觉效果更规整,是实现打字机特效的关键。 - 光标动画:用一个宽度仅 3px 的小方块模拟光标,通过
blink关键帧动画实现 0.9 秒一次的无渐变闪烁,steps(1)属性让闪烁更干脆,贴近真实打字机的光标效果。
2. JS 部分
这里使用 async/await 替代传统的嵌套 setTimeout,让异步流程的代码逻辑更清晰易懂。
sleep工具函数:封装了setTimeout的Promise版本,用来精准控制打字、删除、停顿的时间间隔。type打印函数:先创建光标元素,再遍历文案字符串,在光标前逐个插入字符,每插入一个字符就等待设定的时间,模拟打字节奏。del删除函数:从光标位置往前遍历,逐个删除字符,直到删完一整行,最后移除光标,避免残留。loop主循环函数:通过while(true)实现无限循环,利用取余运算idx = (idx + 1) % lines.length实现文案数组的循环切换,不管数组有多少条文案都能无缝轮播。
四、自定义
特效的扩展性很强,只需修改几行代码就能打造专属效果:
- 修改文案:直接替换
lines数组里的内容,想加多少条文案都可以。 - 调整速度:
typeSpeed越小打字越快,delSpeed越小删除越快,holdDelay可控制文案停留时间,按需调整。 - 美化风格:修改
body的background更换背景色;修改.cursor的background更换光标颜色;还能给文字添加阴影、渐变色等样式。
这个特效非常轻量,不会占用过多资源,无论是嵌入个人博客、作品集页面还是练习项目,都能起到画龙点睛的作用。
