今天刷别人博客的时候,看到了一个有趣的效果->打字
预览、案例、栗子: Demo

前言

刚看到这个效果的时候觉得很惊艳,自己撸了一遍代码->Demo
直到写这篇博客的时候才发现github上面有打字机的开源项目!!!
在这里mark下,下次直接用得了/(ㄒoㄒ)/~~
Github: https://github.com/mattboldt/typed.js/

HTML结构

这部分的结构十分简单, 用两个标签一个存放文本内容、一个用来显示光标

1
2
3
4
<div id="app">
<span class="text"></span>
<span class="cursor cursor-flash">|</span>
</div>

CSS

要注意, 这里光标不能用display属性来控制光标的显示和隐藏,因为这会使html消失导致文本错位,导致效果太核突.
所以这里用opacity属性,通过控制光标的透明度来实现.
首先贴出关键部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#app {
font-size: 48px;
}


.cursor-flash {
animation: flash .7s linear infinite;
}

@keyframes flash {
0% {
opacity: 1;
}

50% {
opacity: 0;
}

100% {
opacity: 1;
}
}

JavaScript

此时光标已经开始闪烁了, 接下来我们只要让文本逐个的添加就好了.
分析了一下效果,有以下几个功能块:

  • 获取节点: querySelector
  • 字符串切割: substr()
  • 定时添加字符串->定时器: setTimeout
  • 打字和删除->异步操作: Promise

code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const str_input = document.querySelector(".text")
let str = "Text cursor Demo!"

function setTextPrint(value) {
return new Promise((resolve, reject) => {
setTimeout(e => {
str_input.innerHTML = value
resolve()
}, 200)
})
}

async function main(flag) {
if (flag) {
for (let i = 0; i <= str.length; i++) {
await setTextPrint(str.substr(0, i))
}
} else {
for (let i = str.length; i >= 0; i--) {
await setTextPrint(str.substr(0, i))
}
}

setTimeout(() => {
main(!flag)
}, 700)
}

main(1)

完善Demo页面

目前页面太过单调, 用CSS修饰一下页面->Demo,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}

body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: radial-gradient(#233, rgb(50, 155, 182));
}

#app {
font-size: 48px;
color: #fff;
}

.cursor {
color: white;
}

.cursor-flash {
animation: flash .7s linear infinite;
}

@keyframes flash {
0% {
opacity: 1;
}

50% {
opacity: 0;
}

100% {
opacity: 1;
}
}
</style>
<!-- <script src="./vue.min.js"></script> -->
</head>

<body>
<div id="app">
<span class="text"></span>
<span class="cursor cursor-flash">|</span>
</div>
<script>
const str_input = document.querySelector(".text")
let str = "Text cursor Demo!"

function setTextPrint(value) {
return new Promise((resolve, reject) => {
setTimeout(e => {
str_input.innerHTML = value
resolve()
}, 200)
})
}

async function main(flag) {
if (flag) {
for (let i = 0; i <= str.length; i++) {
await setTextPrint(str.substr(0, i))
}
} else {
for (let i = str.length; i >= 0; i--) {
await setTextPrint(str.substr(0, i))
}
}

setTimeout(() => {
main(!flag)
}, 700)
}

main(1)

</script>
</body>

</html>