JS+CSS实现逐行逐字输出诗词方法之二
<style>#mydiv {
margin: 20px auto;
padding: 8px 15px;
width: 600px;
height: 400px;
font: bold 2em / 50px sans-serif;
text-shadow: 1px 1px 2px #000;
border: 1px solid gray;
cursor: pointer;
position: relative;
}
</style>
<div id="mydiv"></div>
<script>
let ar = `白居易·忆江南\n\n江南好,\n风景旧曾谙。\n日出江花红胜火,\n春来江水绿如蓝。\n能不忆江南?`.split('\n');
let ziIdx = 0, chars = [], timerId = null,timerFlag = true;
for(let j = 0; j < ar.length; j ++) {
let tmpAr = ar.split('');
if(tmpAr.length === 0) chars.push('<br>');
for(let k = 0; k < tmpAr.length; k ++) {
let tmpStr = '<span style="color: #' + Math.random().toString(16).substr(-6) + '">' + tmpAr + '</span>' + (k < ar.length - 1 ? '' : '<br>');
chars.push(tmpStr);
}
}
let output = () => {
mydiv.innerHTML = '';
for(let j = 0; j < ziIdx; j ++) {
mydiv.innerHTML += chars;
}
ziIdx < chars.length ? ziIdx ++ : ziIdx = 0;
timerId = setTimeout(output,400);
}
timerId = setTimeout(output,200);
mydiv.onclick = () => {
timerFlag ? clearTimeout(timerId) : timerId = setTimeout(output,200);
timerFlag = !timerFlag;
}
</script>
代码:
<style>
#mydiv {
margin: 20px auto;
padding: 8px 15px;
width: 600px;
height: 400px;
font: bold 2em / 50px sans-serif;
text-shadow: 1px 1px 2px #000;
border: 1px solid gray;
cursor: pointer;
position: relative;
}
</style>
<div id="mydiv"></div>
<script>
let ar = `白居易·忆江南\n\n江南好,\n风景旧曾谙。\n日出江花红胜火,\n春来江水绿如蓝。\n能不忆江南?`.split('\n');
let ziIdx = 0, chars = [], timerId = null,timerFlag = true;
for(let j = 0; j < ar.length; j ++) {
let tmpAr = ar.split('');
if(tmpAr.length === 0) chars.push('<br>');
for(let k = 0; k < tmpAr.length; k ++) {
let tmpStr = '<span style="color: #' + Math.random().toString(16).substr(-6) + '">' + tmpAr + '</span>' + (k < ar.length - 1 ? '' : '<br>');
chars.push(tmpStr);
}
}
let output = () => {
mydiv.innerHTML = '';
for(let j = 0; j < ziIdx; j ++) {
mydiv.innerHTML += chars;
}
ziIdx < chars.length ? ziIdx ++ : ziIdx = 0;
timerId = setTimeout(output,400);
}
timerId = setTimeout(output,200);
mydiv.onclick = () => {
timerFlag ? clearTimeout(timerId) : timerId = setTimeout(output,200);
timerFlag = !timerFlag;
}
</script>
说明:
这个没有CSS太多事,关键是JS。思路是,将文本拆分成单字,放入一个数组,拆分时遇到 \n 则将其变为 <br> 并放在它前面的字的后面做换行符。然后设计一个函数 output(),作用是在指定的间隔时间内将数组里的内容输出到父窗体,每一次执行会比前一次执行的多出一个数组元素的内容,这么做的结果就是好像每一次执行此函数都是单字上屏的效果。
ziIdx是至关重要的变量,它是数组索引,函数 output() 每执行一次它就步进1,诗词一次输出完毕它又变回0,这就是之前发布的在两个数间循环遍历脚本的应用实例。文本上屏可以暂停/继续依靠的就是这个 ziIdx 变量,省去了定时器其他开发的编程开销。
先看看,再在实践应用中学习 点击可暂停⏸️ 南无月 发表于 2023-5-22 12:32
点击可暂停⏸️
对,这个能暂停 感谢老师的代码分享,欣赏问好!{:4_187:} 黑黑厉害,不断能做出JS+CSS的逐字逐行输出,还能做出两种方式来。很赞{:4_199:} 这个文字输入是在JS里的,做起来更加准确,还能暂停,肯定比前一个更好。但从理解上,貌似前面那个更好理解点{:4_173:} 无论怎样,都必须给黑黑点一个大大的赞,太厉害了{:5_116:}{:4_199:} 马黑黑 发表于 2023-5-22 12:55
对,这个能暂停
能行能停十分完美 南无月 发表于 2023-5-22 17:55
能行能停十分完美
相对而言,和帖子的相关控制可以合拍 红影 发表于 2023-5-22 17:39
无论怎样,都必须给黑黑点一个大大的赞,太厉害了
逐个段落(或叫行)加逐字上屏难度是比较大的,我见过网上有很多人也在纠结这个问题,一个比较理想的方案是用jQuery或其他框架实现,不过呢,像这个帖子所展示的那样,原生JS也是可以办到的 马黑黑 发表于 2023-5-22 18:11
逐个段落(或叫行)加逐字上屏难度是比较大的,我见过网上有很多人也在纠结这个问题,一个比较理想的方案 ...
原生JS也需要黑黑这样的高手才能实现呢{:4_187:} 红影 发表于 2023-5-22 19:43
原生JS也需要黑黑这样的高手才能实现呢
会JS的,用心去做,会比我做得好 马黑黑 发表于 2023-5-22 20:22
会JS的,用心去做,会比我做得好
队伍这样不会的,就什么都谈不上了{:4_173:} 红影 发表于 2023-5-22 20:57
队伍这样不会的,就什么都谈不上了
会的自然会 马黑黑 发表于 2023-5-22 21:03
会的自然会
队伍==对我,又打错字了{:4_170:} 红影 发表于 2023-5-22 21:53
队伍==对我,又打错字了
我就是五呀,知道的。520,就是我饿了的意思呀