一、实现
1、基本思路是:
- 将装有文章的字符串切割成数组,
- 动态添加
span
标签,标签内容通过每次把数组的第一个切割出来去填充进去
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA_Compatible" content="IE-edge" />
<meta name="viewport" content="width=device=width,initial-scale=1.0" />
<title>文字逐渐显示</title>
<style>
body {
padding: 0;
background-color: antiquewhite;
text-align: center;
}
#main {
width: 90vw;
display: inline-block;
line-height: 20px;
padding: 10px;
background-color: rgb(233, 221, 187, .5);
text-align: left;
}
</style>
</head>
<body>
<div id="main"></div>
</body>
<script>
let str = "先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。\n\n宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。\n\n侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。\n\n将军向宠,性行淑均,晓畅军事,试用于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。\n\n亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。\n\n臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。\n\n先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐托付不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。\n\n愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。\n\n今当远离,临表涕零,不知所言。";
let main = document.getElementById('main');
let words = str.split('');
let showWords = () => {
if (words.length > 0) {
let spanEl = document.createElement('span');
let del = words.shift();
let opc = 0;
spanEl.innerHTML = del;
main.appendChild(spanEl);
}
}
setInterval(showWords, 50)
</script>
</html>
2、每个字添加进去之后的一些动态效果
这是对于文字逐步添加的一个思路,那么还有文字一个一个得出来的效果,当然直接添加也是可以的,总归是突兀且不够美观的。
这里需要说的是,对于每个字添加进去之后的一些动态效果,阴影、蒙层、透明度等,因为是一个一个进去的那么这些效果的添加也是需要一个过渡的不能一下很突然的就有了这个效果。实现这个有两种方式
- 一种是js定时器实现,在元素添加进去之后用定时器逐个添加效果,这里的过渡使用的
filter
的blur
代码如下:
let fade = setInterval(() => {
opc++;
spanEl.style.opacity = opc / 10;
spanEl.style.color = 'transparent';
spanEl.style.textShadow = '0 0 5px #57606f,0 0 10px #57606f,0 0 4px #57606f,0 0 12px #ffa502';
//将高斯模糊添加于span
spanEl.style.filter = `blur(${(10 / opc - 1)}px)`;
if (opc >= 10) {
clearInterval(fade);
spanEl.style.color = '#2f3542';
}
}, 50)
- animation 实现蒙层及文字阴影效果。设置关键帧,给
span
添加动画
#main span.showWords {
text-shadow: 0 0 5px #57606f, 0 0 10px #57606f, 0 0 4px #57606f, 0 0 12px #ffa502;
animation: showWords 5s;
-webkit-animation: showWords 5s;
/*Safari and Chrome*/
}
@keyframes showWords {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes showWords
/*Safari and Chrome*/
{
from {
opacity: 0;
}
to {
opacity: 1;
}
}
spanEl.className = 'showWords';
二、涉及知识
1、shift
Array.prototype.shift()
shift()
方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
1.1 语法
shift()
1.2 返回值
- 从数组中删除的元素;如果数组为空则返回
undefined
。
1.3 描述
-
shift
方法移除索引为 0 的元素,并将后续元素的下标依次向前移动,然后返回被移除的元素。如果length
属性的值为 0,则返回undefined
。 -
pop()
方法有着和shift()
相似的行为。但是是作用于数组的最后一个元素上的。 -
shift()
方法是一个改变方法。它改变了this
的内容和长度。如果你希望保持 this 的值不变,但返回一个删除了第一个元素的新数组,你可以使用arr.slice(1)
。 -
shift()
方法是通用的。它只期望this
值具有length
属性和整数键属性。虽然字符串也是类似数组的,但这个方法不适合应用于它们,因为字符串是不可变的。
1.4 示例
1.4.1 移除数组中的一个元素
上面这个文字逐渐显示的效果里面用的就是这个
1.4.2 在 while 循环中使用 shift()
shift()
方法经常用于 while
循环的条件中。
下例中每次迭代都会从一个数组中移除下一项元素,直至它成为空数组。
const names = ["Andrew", "Tyrone", "Paul", "Maria", "Gayatri"];
while (typeof (i = names.shift()) !== "undefined") {
console.log(i);
}
// Andrew, Tyrone, Paul, Maria, Gayatri
1.4.3 在非数组对象上调用 shift()
shift
方法会读取this
的length
属性。
如果规范化长度为
0
,length
再次设置为0
(而之前可能为负值或undefined
)。
否则,返回
0
处的属性,其余属性向左移动1
。length
属性递减1
。
const arrayLike = {
length: 3,
unrelated: "foo",
2: 4,
};
console.log(Array.prototype.shift.call(arrayLike));
// undefined,因为它是一个空槽
console.log(arrayLike);
// { '1': 4, length: 2, unrelated: 'foo' }
const plainObj = {};
// 这里没有长度属性,所以长度为 0
Array.prototype.shift.call(plainObj);
console.log(plainObj);
// { length: 0 }
2、animation
animation
属性是animation-name
,animation-duration
,animation-timing-function
,animation-delay
,animation-iteration-count
,animation-direction
,animation-fill-mode
和animation-play-state
属性的一个简写属性形式。
2.1 语法
/* @keyframes duration | easing-function | delay |
iteration-count | direction | fill-mode | play-state | name */
animation: 3s ease-in 1s 2 reverse both paused slidein;
/* @keyframes duration | easing-function | delay | name */
animation: 3s linear 1s slidein;
/* two animations */
animation:
3s linear slidein,
3s ease-out 5s slideout;
animation
属性用来指定一组或多组动画,每组之间用逗号相隔。
2.2 demo中的使用
animation知识点蛮多的,这里只说一下这个里面的使用
@keyframes
设置关键帧
@keyframes 关键帧名称 {
from {
//动画开始时的样式
opacity: 0;
}
to {
//动画结束时的样式
opacity: 1;
}
}
- animation使用关键帧
animation: 关键帧名称 过渡时间;
animation: showWords 5s;