该案例学习自B站UP主xiao-high
打印多条文段可以参考一下这里:传送门。案例见博客个人简介的应用,点这里看效果。(打印一段文字后,再打印一段,覆盖前边的内容)
介绍
文本一个一个的显示,同时有光标闪烁效果。
点击这里查看效果:传送门
动手制作
新建一个HTML文件。
1 |
|
body
添加一个div,class名为text,用于控制文本和光标的大小。div内部添加两个span,分别作为文本和光标的容器。光标为符号|
。
1 |
<div class="text"> |
css
去除浏览器默认的margin、padding值。
1 |
* { |
body设置让div居中显示,设置一个径向渐变背景。
1 |
body { |
设置div内的字体颜色为白色,字体大小在后边js代码中设置。
1 |
.text { |
实现光标闪烁
制作光标闪烁动画:动画设置两帧,透明度从0到100。
1 |
@keyframes flash { |
光标应用该动画,动画播放时间为0.5秒,线性播放,循环播放。同时设置左外边距为5px。
1 |
.text .gbiao { |
script
参数说明:
- fontSize,字体大小
- word,显示文本的span标签
- str,文本
在进行绘制之前,我们需要确定打开HTML文件的设备是pc还是手机。从而指定不同的fontSize。
1 |
var ua = navigator.userAgent.toLowerCase(); |
设置文本大小
1 |
//设置文本大小 |
上边的js代码可以使用CSS中的@media 查询
来实现,具体代码如下:
在前边css的.text
中添加字体大小:(PC端)
1 |
font-size: 28px; |
在前边的css后边再添加一个style
标签,指定移动端的字体大小。代码如下:
1 |
<style type="text/css"> |
判断设备类型的js代码和设置文本大小的js代码就可以删掉了。
添加要显示的文本
1 |
let str = "你好,我是码代码的冰果果!很高兴见到你!"; //要显示的文本 |
通过class名选择显示文本的span标签
1 |
//获取文本显示的span |
实现打字机效果
有了str和word我们就可以实现打字机效果了。将实现打字机效果封装在一个方法内,方法名showText
1 |
//实现打字机效果 |
我们定义几个变量:
- myflag,布尔值,用于后边的正倒放中
- time,每个字符显示的时间长度
- timewait,正倒放等待时间
1 |
let myflag = true; |
实现正放
我们规定,正放就是从没有显示字符到显示出全部的文本的过程。反之为倒放。
正放思路:使用一个for循环,循环次数为要显示的文本的个数,每进入一个循环就截取要显示的文本的一部分显示在页面上。例如第一次进入for循环,截取“你”;第二次进入for循环,截取“你好”;第三次进入for循环,截取“你好,”;第四次进入for循环,截取“你好,我”;。。。代码实现如下:
1 |
for (let n = 1; n <= str.length; n++) { //正放 |
可是电脑运行速度都是很快的,一瞬间for循环就执行完了,也就是说我们看不到文本一个一个的显示出来。我们需要控制每一次截取文本显示到页面的时间。
我们可以使用一个定时器,隔指定时间执行定义在其内部的函数。前边我们定义了每个字符显示的时间为time=300毫秒,前一个字符等待显示的时间为0,前两个字符等待显示的时间为time,前三个字符等待显示的时间为两个time,前四个字符等待显示的时间为三个time,。。。所以越往后时间越长。代码实现如下:
1 |
setTimeout(function (){ |
所以实现正放代码应该为:
1 |
for (let n = 1; n <= str.length; n++) { //正放 |
实现倒放
倒放与正放刚刚好相反。正放是先显示前一个字符,再显示前两个字符,。。。倒放是先显示全部的字符,然后少显示一个,再然后少显示两个,。。。所以j的初始值为字符的长度str.length
。时间变成了str.length
- j
,j越来越小,str.length
不变,所以越往后时间越长,跟前边正放一样。代码实现如下:
1 |
for (let j = str.length; j >= 0; j--) { //倒放 |
正/倒放结合
实现的效果是先正放,然后倒放,再然后是正放一直循环下去。这里我们需要用到一个周期定时器,每隔一定的时间(正放或倒放结束后),就执行一次倒放或正放。
1 |
setInterval(function (){ |
每隔一定的时间,这个时间我们可以通过str.length * time
来计算,str.length * time
为一次正放或倒放所用的时间,如果想让正放倒放相隔一定的时间,我可以再添加一个等待时间,即前边定义的timewait。
1 |
setInterval(function (){ |
要实现一次正放一次倒放交替执行,我们需要用到在前边定义的布尔类型变量myflag,配合if-else语句即可实现。代码如下:
1 |
if(myflag){ |
所以正/倒放结合完整代码如下:
1 |
setInterval(function(myflag) { |
到这里,实现打字机效果的函数showText,貌似就已经完成了。不过我在实际的测试中发现有一个bug,与传递到周期定时器内的参数myflag有关。导致第一次正放没有显示,到了倒放才开始显示文本。这个bug目前我修复不了,不过我在周期定时器的前边添加了一个正放,可以掩盖掉那个bug。如果你解决了这个bug请一定要跟我分享一下解决方法。函数showText未掩盖bug的完整代码如下:
1 |
//实现打字机效果 |
函数showText掩盖bug后的完整代码如下:
1 |
//实现打字机效果 |
最后,我们需要调用一下这个函数,才能使打字机效果生效。我这里是添加了一个定时器,页面加载完成之后过1s再调用实现打字机效果的函数。代码如下:
1 |
//打开页面1s后显示文本 |
源码
至此全部的代码都完成了。下边是全部代码整合:
1 |
|
修复bug
使用闭包来解决bug,详细笔记访问这里。(这里的也是使用了闭包,不过定时器内并没有使用到外边定义的标志位myflag
,函数定义的问题。定时器内的this.myflag
不是外边定义的myflag
,而是匿名函数传递进来的空值重新被后边的this.myflag
= !this.myflag;
语句赋值了的定时器内的局部变量,所以第一次没有执行if中的正放代码是因为其值为null。解决方法是把定时器内的匿名函数拿出来,定时器内调用函数名即可。)
修复bug
下边的方法已经废弃,有了更好的实现方法。已放到上边。这里的方法也可以实现效果,但是过于凌乱。
其实bug并没有修复,而是使用了另一种方法来实现打字机效果。将正、倒放单独作为一个函数,不过在正放的函数结束后调用倒放的函数。再使用一个函数调用正放的函数。
正、倒放函数,
positive(element,str, time, timewait)、reverse(element,str, time, timewait)
各形参分别为:显示文本的容器,显示的文本,一个字符显示时间,正倒放间隔时间
正、倒放函数都是在正、倒放操作的基础上加一个定时器,添加等待时间
1
2
3
4
5
6
7
8
9
10
11
12
13//倒放
setTimeout(function() {
//内部的实现代码与前边的一样,并未修改
for (let j = str.length; j >= 0; j--) { //倒放
setTimeout(function() { //定时器
element.innerHTML = str.substr(0, j);
}, (str.length - j) * time);
}
}, timewait);//使用定时器增加等待时间正放函数的后边调用倒放函数,计算好正放时间加等待时间后使用定时器调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//正放
setTimeout(function() {
for (let i = 1; i <= str.length; i++) { //正放
setTimeout(function() { //定时器
element.innerHTML = str.substr(0, i);
}, (i - 1) * time);
}
//调用倒放
setTimeout( 调用倒放 , 正放所用时间+等待时间 );
}, timewait);//播放前的等待时间
调用正放的函数,
showText02(element, str, num,time,timewait)
,形参有:显示文本的容器,显示的文本,播放次数(正+倒为一次),一个字符显示时间,正倒放间隔时间- 使用for循环,实现指定的播放次数。不过在调用正放函数时需要使用定时器。
- 可以将正放的函数看作是一次正放加倒放(正放后边调用了倒放),所以定时器的时间可以设置为一次正放的时间+一次倒放的时间+两个等待时间,即:
str.length * time * 2 + timewait*2
- showText02有四个参数,但是我们可以内置字符显示时间(200ms)、等待时间(2000ms)和播放次数 (1次),使用时如果不想频繁设置这些参数,只需要给显示文本的容器和要显示的文本两个参数即可。
使用:
1 |
//获取文本显示的span(显示文本的容器) |
实现打字机效果的一些函数:
1 |
//实现方法2 |
完整源代码如下:
1 |
|