日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

实现打字机特效

發(fā)布時間:2024/3/26 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现打字机特效 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

該案例學習自B站UP主xiao-high

打印多條文段可以參考一下這里:傳送門。案例見博客個人簡介的應用,點這里看效果。(打印一段文字后,再打印一段,覆蓋前邊的內容)

介紹

文本一個一個的顯示,同時有光標閃爍效果。

點擊這里查看效果:傳送門

動手制作

新建一個HTML文件。

<!DOCTYPE html> <html> <head><meta charset="utf-8" /><title>qsdbl</title> </head> <body></body> </html>

body

添加一個div,class名為text,用于控制文本和光標的大小。div內部添加兩個span,分別作為文本和光標的容器。光標為符號|。

<div class="text"><span class="word"></span><span class="gbiao">|</span> </div>

css

去除瀏覽器默認的margin、padding值。

* {margin: 0;padding: 0; }

body設置讓div居中顯示,設置一個徑向漸變背景。

body {height: 100vh;/*讓文本居中*/display: flex;align-items: center;justify-content: center;/*徑向漸變*/background: radial-gradient(#000000, rgb(31, 77, 20)); }

設置div內的字體顏色為白色,字體大小在后邊js代碼中設置。

.text {color: #fff;text-align:center; }

實現光標閃爍

制作光標閃爍動畫:動畫設置兩幀,透明度從0到100。

@keyframes flash {from {opacity: 0;}to {opacity: 1;} }

光標應用該動畫,動畫播放時間為0.5秒,線性播放,循環(huán)播放。同時設置左外邊距為5px。

.text .gbiao {margin-left: 5px;animation: flash 0.5s linear infinite;/*讓光標閃爍*/ }

script

參數說明:

  • fontSize,字體大小
  • word,顯示文本的span標簽
  • str,文本

在進行繪制之前,我們需要確定打開HTML文件的設備是pc還是手機。從而指定不同的fontSize。

var ua = navigator.userAgent.toLowerCase(); if(/AppleWebKit.*Mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|ZTE/.test(navigator.userAgent)) || ua.match(/MicroMessenger/i) == "micromessenger"){var fontSize = 50;//手機字體大小 }else{var fontSize = 28;//pc字體大小 }

設置文本大小

//設置文本大小let textSize = document.querySelector('.text');textSize.style.fontSize = fontSize + "px";

上邊的js代碼可以使用CSS中的@media 查詢來實現,具體代碼如下:

在前邊css的.text中添加字體大小:(PC端)

font-size: 28px;

在前邊的css后邊再添加一個style標簽,指定移動端的字體大小。代碼如下:

<style type="text/css"> @media(max-width: 500px) {.text{font-size: 50px;} } </style>

判斷設備類型的js代碼和設置文本大小的js代碼就可以刪掉了。

添加要顯示的文本

let str = "你好,我是輕率的保羅!很高興見到你!"; //要顯示的文本

通過class名選擇顯示文本的span標簽

//獲取文本顯示的span let word = document.querySelector('.word');

實現打字機效果

有了str和word我們就可以實現打字機效果了。將實現打字機效果封裝在一個方法內,方法名showText

//實現打字機效果 function showText() {}

我們定義幾個變量:

  • myflag,布爾值,用于后邊的正倒放中
  • time,每個字符顯示的時間長度
  • timewait,正倒放等待時間
let myflag = true; let time = 300; //每個字符顯示的時間 let timewait = 2000; //正倒放等待時間

實現正放

我們規(guī)定,正放就是從沒有顯示字符到顯示出全部的文本的過程。反之為倒放。

正放思路:使用一個for循環(huán),循環(huán)次數為要顯示的文本的個數,每進入一個循環(huán)就截取要顯示的文本的一部分顯示在頁面上。例如第一次進入for循環(huán),截取“你”;第二次進入for循環(huán),截取“你好”;第三次進入for循環(huán),截取“你好,”;第四次進入for循環(huán),截取“你好,我”;。。。代碼實現如下:

for (let n = 1; n <= str.length; n++) { //正放word.innerHTML = str.substr(0, n); } //substr(start,length)方法可在字符串中抽取從 start 下標開始的指定數目的字符。

可是電腦運行速度都是很快的,一瞬間for循環(huán)就執(zhí)行完了,也就是說我們看不到文本一個一個的顯示出來。我們需要控制每一次截取文本顯示到頁面的時間。

我們可以使用一個定時器,隔指定時間執(zhí)行定義在其內部的函數。前邊我們定義了每個字符顯示的時間為time=300毫秒,前一個字符等待顯示的時間為0,前兩個字符等待顯示的時間為time,前三個字符等待顯示的時間為兩個time,前四個字符等待顯示的時間為三個time,。。。所以越往后時間越長。代碼實現如下:

setTimeout(function (){word.innerHTML = str.substr(0, n); },(n - 1) * time);//單位是毫秒

所以實現正放代碼應該為:

for (let n = 1; n <= str.length; n++) { //正放setTimeout(function() { //定時器word.innerHTML = str.substr(0, n);}, (n - 1) * time); }

實現倒放

倒放與正放剛剛好相反。正放是先顯示前一個字符,再顯示前兩個字符,。。。倒放是先顯示全部的字符,然后少顯示一個,再然后少顯示兩個,。。。所以j的初始值為字符的長度str.length。時間變成了str.length - j ,j越來越小,str.length不變,所以越往后時間越長,跟前邊正放一樣。代碼實現如下:

for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時器word.innerHTML = str.substr(0, j);}, (str.length - j) * time); }

正/倒放結合

實現的效果是先正放,然后倒放,再然后是正放一直循環(huán)下去。這里我們需要用到一個周期定時器,每隔一定的時間(正放或倒放結束后),就執(zhí)行一次倒放或正放。

setInterval(function (){},毫秒數);

每隔一定的時間,這個時間我們可以通過str.length * time來計算,str.length * time為一次正放或倒放所用的時間,如果想讓正放倒放相隔一定的時間,我可以再添加一個等待時間,即前邊定義的timewait。

setInterval(function (){}, str.length * time + timewait);

要實現一次正放一次倒放交替執(zhí)行,我們需要用到在前邊定義的布爾類型變量myflag,配合if-else語句即可實現。代碼如下:

if(myflag){//正放 }else{//倒放 } myflag = !myflag;

所以正/倒放結合完整代碼如下:

setInterval(function(myflag) {if (this.myflag) {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時器word.innerHTML = str.substr(0, i);}, (i - 1) * time);}} else {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時器word.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}this.myflag = !this.myflag; }, str.length * time + timewait);

到這里,實現打字機效果的函數showText,貌似就已經完成了。不過我在實際的測試中發(fā)現有一個bug,與傳遞到周期定時器內的參數myflag有關。導致第一次正放沒有顯示,到了倒放才開始顯示文本。這個bug目前我修復不了,不過我在周期定時器的前邊添加了一個正放,可以掩蓋掉那個bug。如果你解決了這個bug請一定要跟我分享一下解決方法。函數showText未掩蓋bug的完整代碼如下:

//實現打字機效果 function showText() {let myflag = true;let time = 300; //每個字符顯示的時間let timewait = 2000; //正倒放等待時間setInterval(function(myflag) {if (this.myflag) {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時器word.innerHTML = str.substr(0, i);}, (i - 1) * time);}} else {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時器word.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}this.myflag = !this.myflag;}, str.length * time + timewait); }

函數showText掩蓋bug后的完整代碼如下:

//實現打字機效果 function showText() {let myflag = true;let time = 300; //每個字符顯示的時間let timewait = 2000; //正倒放等待時間for (let n = 1; n <= str.length; n++) { //正放setTimeout(function() { //定時器word.innerHTML = str.substr(0, n);}, (n - 1) * time);}setInterval(function(myflag) {if (this.myflag) {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時器word.innerHTML = str.substr(0, i);}, (i - 1) * time);}} else {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時器word.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}this.myflag = !this.myflag;}, str.length * time + timewait); }

最后,我們需要調用一下這個函數,才能使打字機效果生效。我這里是添加了一個定時器,頁面加載完成之后過1s再調用實現打字機效果的函數。代碼如下:

//打開頁面1s后顯示文本 setTimeout(showText, 1000);

源碼

至此全部的代碼都完成了。下邊是全部代碼整合:

<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>qsdbl</title></head><body><div class="text"><span class="word"></span><span class="gbiao">|</span></div></body><style>* {margin: 0;padding: 0;}body {height: 100vh;/*讓文本居中*/display: flex;align-items: center;justify-content: center;/*徑向漸變*/background: radial-gradient(#000000, rgb(31, 77, 20));}.text {color: #fff;}.text .gbiao {margin-left: 5px;animation: flash 0.5s linear infinite;/*讓光標閃爍*/font-weight: bold;}@keyframes flash {from {opacity: 0;}to {opacity: 1;}}</style><script>var ua = navigator.userAgent.toLowerCase();if (/AppleWebKit.*Mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|ZTE/.test(navigator.userAgent)) || ua.match(/MicroMessenger/i) == "micromessenger") {var fontSize = 50; //手機字體大小} else {var fontSize = 28; //pc字體大小}//設置文本大小let textSize = document.querySelector('.text');textSize.style.fontSize = fontSize + "px";let str = "你好,我是輕率的保羅!很高興見到你!"; //要顯示的文本//獲取文本顯示的spanlet word = document.querySelector('.word');//打開頁面1s后顯示文本setTimeout(showText, 1000);//實現打字機效果function showText() {let myflag = true;let time = 300; //每個字符顯示的時間let timewait = 2000; //正倒放等待時間for (let n = 1; n <= str.length; n++) { //正放setTimeout(function() { //定時器word.innerHTML = str.substr(0, n);}, (n - 1) * time);}setInterval(function(myflag) {if (this.myflag) {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時器word.innerHTML = str.substr(0, i);}, (i - 1) * time);}} else {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時器word.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}this.myflag = !this.myflag;}, str.length * time + timewait);}</script> </html>

修復bug

使用閉包來解決bug,詳細筆記訪問這里。(這里的也是使用了閉包,不過定時器內并沒有使用到外邊定義的標志位myflag,函數定義的問題。定時器內的this.myflag不是外邊定義的myflag,而是匿名函數傳遞進來的空值重新被后邊的this.myflag = !this.myflag;語句賦值了的定時器內的局部變量,所以第一次沒有執(zhí)行if中的正放代碼是因為其值為null。解決方法是把定時器內的匿名函數拿出來,定時器內調用函數名即可。)

打字機效果案例源碼:https://cloud.189.cn/t/MbYraiArERrq(訪問碼:hzj6)

修復bug

下邊的方法已經廢棄,有了更好的實現方法。已放到上邊。這里的方法也可以實現效果,但是過于凌亂。

其實bug并沒有修復,而是使用了另一種方法來實現打字機效果。將正、倒放單獨作為一個函數,不過在正放的函數結束后調用倒放的函數。再使用一個函數調用正放的函數。

  • 正、倒放函數,positive(element,str, time, timewait)、reverse(element,str, time, timewait)

    • 各形參分別為:顯示文本的容器,顯示的文本,一個字符顯示時間,正倒放間隔時間

    • 正、倒放函數都是在正、倒放操作的基礎上加一個定時器,添加等待時間

      //倒放 setTimeout(function() {//內部的實現代碼與前邊的一樣,并未修改for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時器element.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}, timewait);//使用定時器增加等待時間
    • 正放函數的后邊調用倒放函數,計算好正放時間加等待時間后使用定時器調用

      //正放 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循環(huán),實現指定的播放次數。不過在調用正放函數時需要使用定時器。
    • 可以將正放的函數看作是一次正放加倒放(正放后邊調用了倒放),所以定時器的時間可以設置為一次正放的時間+一次倒放的時間+兩個等待時間,即:str.length * time * 2 + timewait*2
    • showText02有四個參數,但是我們可以內置字符顯示時間(200ms)、等待時間(2000ms)和播放次數 (1次),使用時如果不想頻繁設置這些參數,只需要給顯示文本的容器要顯示的文本兩個參數即可。

使用:

//獲取文本顯示的span(顯示文本的容器) let word = document.querySelector('.word'); showText02(word,str,4);//顯示文本的容器、顯示的文本,播放次數(正+倒為一次),一個字符顯示時間,正倒放間隔時間

實現打字機效果的一些函數:

//實現方法2 function showText02(element,str, num,time,timewait) {//time,每個字符顯示的時間,建議200毫秒//timewait,正倒放等待時間,建議2000毫秒//num,播放次數,默認一次if(time == null){time = 200;}if(timewait == null){timewait = 2000;}if(num == null){num = 1;}for (var i = 0; i < num; i++) {//for循環(huán)控制播放次數setTimeout(function() {positive(element,str, time, timewait);}, (str.length * time * 2 + timewait*2) * i);//括號內的時間為一次正加一次倒} } //正放 function positive(element,str, time, timewait) {setTimeout(function() {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時器element.innerHTML = str.substr(0, i);}, (i - 1) * time);}setTimeout(function() {reverse(element,str, time);}, str.length * time + timewait);//正放結束后再開始倒放,使用定時器增加正放時間和結束后的等待時間}, timewait);//播放前的等待時間 } //倒放 function reverse(element,str, time, timewait) {setTimeout(function() {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時器element.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}, timewait);//使用定時器增加等待時間 }

完整源代碼如下:

<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>qsdbl</title></head><body><div class="text"><span class="word"></span><span class="gbiao">|</span></div></body><style type="text/css">* {margin: 0;padding: 0;}body {height: 100vh;/*讓文本居中*/display: flex;align-items: center;justify-content: center;/*徑向漸變*/background: radial-gradient(#000000, rgb(64, 204, 15));}.text {color: #fff;/*0f0*/text-align: center;font-size: 40px;font-weight: bold;}.text .gbiao {margin-left: 5px;animation: flash 0.5s linear infinite;/*讓光標閃爍*/}@keyframes flash {from {opacity: 0;}to {opacity: 1;}}</style><style type="text/css">/*當顯示設備為手機時,字體大小設置為20px。(用于判斷設備類型的500px是一個經驗值)*/@media(max-width:500px) {.text {font-size: 20px;}}</style><script>let str = "你好,我是輕率的保羅!很高興見到你!"; //要顯示的文本//獲取文本顯示的span(顯示文本的容器)let word = document.querySelector('.word');//播放4次showText02(word,str,4);//顯示文本的容器,顯示的文本,播放次數(正+倒為一次),一個字符顯示時間,正倒放間隔時間//實現打字機效果(下邊為封裝的函數)function showText02(element,str, num,time,timewait) {//time,每個字符顯示的時間,建議200毫秒//timewait,正倒放等待時間,建議2000毫秒if(time == null){time = 200;}if(timewait == null){timewait = 2000;}if(num == null){num = 1;}for (var i = 0; i < num; i++) {//for循環(huán)控制播放次數setTimeout(function() {positive(element,str, time, timewait);}, (str.length * time * 2 + timewait*2) * i);//括號內的時間為一次正加一次倒}}//正放function positive(element,str, time, timewait) {setTimeout(function() {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時器element.innerHTML = str.substr(0, i);}, (i - 1) * time);}setTimeout(function() {reverse(element,str, time);}, str.length * time + timewait);//正放結束后再開始倒放,使用定時器增加正放時間和結束后的等待時間}, timewait);//播放前的等待時間}//倒放function reverse(element,str, time, timewait) {setTimeout(function() {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時器element.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}, timewait);//使用定時器增加等待時間}</script> </html>

原文鏈接:實現打字機特效

總結

以上是生活随笔為你收集整理的实现打字机特效的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。