typer.js,可能是最小但功能也不多的模拟打字效果插件

typer.js是一个仅1.6 Kb的JavaScript插件,用于实现打字、删除、重复和停顿的打字机效果。作者因在制作在线简历时需要该效果,但现有插件体积过大,故自行研发。通过控制事件顺序和链式调用来实现功能,并用伪元素创建闪烁光标。源码已开源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

打字机效果文字插件typer.js


typer.js介绍

typer.js是模拟打字机效果的轻型js插件(1.6 Kb),有打字、删除、重复和停顿几种简单的效果。

起因

由于这几天写个在线简历,我想使用打字的特效,在github上搜到一个叫TheaterJS的插件,效果很好,但是应用时发现,TheaterJS开发版的体积近80kb,而且我只需要它的打字机效果,不需其他复杂的功能,于是又萌生了自己造轮子的想法。

构思

之前写的listen2me用过类似的文字单播的效果,加上见过许多其他打字机效果,心里觉得还是有底的。

想了想自己的需求,效果上分为两块:

  1. 文字逐个显示
  2. 闪烁的光标

在使用上需要:

  1. 输出内容控制简便,模仿TheaterJs输出时的链式调用方法。
  2. 控制速度、停顿等

研究过程

一些错误的想法

打字效果很简单,简单的JS代码配合CSS就很好的还原了TheaterJS的效果,当然这仅是一行文字的输出。

然后研究输出控制。刚开始单纯的以为借用JQUERY可以直接链式调用与事件的顺序执行,具体写代码才发现,jquery的链式调用是操作节点的,而且它的内置函数应该都设定好了对链式操作的支持,我在网上查阅了一些资料,js可以通过对函数return this来支持链式调用。

又研究了事件的顺序,同样,本以为jquery的链式调用可以按顺序执行,比如$('DOM').fadeIn().fadeOut().animate(....)这个操作就是按照淡入、淡出再动画的顺序进行的,后面的操作会等待前面的完成。写代码时又发现,我写的js无法以这个思路实现按序执行,因为打字效果要使用setTimeout这个函数,使得整个过程成为异步,JS执行时自然无法有序。看了一些JQUERY代码,发现除了链式调用外,可以按序执行代码的方法还有使用callback,比如``$('DOM').animate({'width':'100%'},1000,function(){........})

然后自己陷入了混乱,再乱试了各种方法之后,选择了睡觉。

今天早起,突然就想清楚昨天尝试的方法问题在哪里,比如这段事件等待:

while (!isTyping) {
  this.isTyping = true;
  speed = speed ? speed : this.speed;
  var duration = text.length * speed;
  var set = function() {
    isTyping = true;
  }
  for (var i = 0; i < text.length; i++) {
    setTimeout(addText, speed * i, text.charAt(i));
    setTimeout(function() {
      isTyping = false;
    }, duration);
    set()
  }
}

用while其实是个死循环。

我的本意是建立一个isTyping标志,当第一个打字事件开始时,isTyping为true,这样第二个事件会因为while的条件不成立,一直在空转等待前一个事件完成时isTyping为false。但是,第一个事件完成时,isTyping为false的瞬间,仍是在while循环体内,又触发了while (!isTyping),所以永远都轮不到第二个事件,永远都停在了第一个事件内。

正确的思路

事件的顺序

继而决定使用想到的第二种思路,将所有的打字事件,计算出所消耗的时间,使用setTimeout将每个事件用时累加起来,作为下一个事件的开始事件,也就是说:

a事件:    typer.type('this is the first paragraph')
b事件:    typer.type('this is the second paragraph')
.....
n事件:    typer.type('this is the first paragraph')

a事件需要比如10s,那么b事件的开始时间就是10s后,也就是setTimeout(b事件,10000),依次类推,这样所有的打字事件都可以由setTimeout控制其顺序了。

链式调用

再给每个type函数加上return this,这样就可以链式调用了:

var babyTyper = new typer(DOM);
babyTyper
.type('I am a babyTyper')
.type('and I love typing in this way')
.type('I feel so happy!')

或者这样

babyTyper.type('I am brother of that guy,').type(' I love typing in a row, ').type('because it is cool!')

闪烁的打字光标效果

刚开始研究效果时,使用过INPUT输入框,去除边框borderoutlook后,只需获得输入焦点,JS将文字输入到input即可,同样是打字的效果,但是有一点不足,无法控制闪烁光标的样式,因为这个光标是继承自系统的,无论怎么调节CSS字体样式,光标都是那么细小,跳动的频率也控制不了。

这里就借鉴了TheaterJS的方法,使用::after伪元素给内容加入一个动画内容:

.typer-place::after {
content: '|';
animation: blink 800ms infinite;
}
@keyframes blink {
  from { opacity: 0; }
  to { opacity: 1; }
}

这样就实现了打字时闪烁光标的效果。

循环重复

功能都完成后,我又想到需要一个循环播放的功能。想了一会,想到一个最基础的方法,就是建立一个记录操作的方法,把每次的输出与删除都按顺序记录。然后再把记录的内容再次执行就可以。看了几个源码,他们写的重复也是记录操作再次执行。

但是我总觉得这样太麻烦,不够简便,不如想一种方法无需记录,直接重复。查阅了些资料,好像没有什么现成的例子重复执行代码的,最终写成如下:

var typer = new typer(DOM);
setInterval(repeat,typer.duration)
function repeat(){
  typer.type('测试')
  typer.type('测试')
  typer.type('测试')
}

这个逻辑很清晰,我很喜欢,但是写出来的内容太多了,不够简洁。最终我还是选择了记录操作,实现重复只需一个方法typer.repeat()

以上几点是代码的关键部分,完成之后,其余的内容都相对简单,很快就处理完了。

源码及使用

源码在我的github

typer.js

使用方法很简单

<script src="typer.js"></script>
<script>
  var typer = new typer('DOM的ID'))
  typer.type('hi~')
  typer.type('当然也可以按照链式调用那样省略typer')
</script>

具体使用方法参见github readme

小结

总体来讲,就是打字事件按顺序调用和寻找简便重复方法这两部分想的挺久的,其余都很简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值