日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

实现打字机特效

發(fā)布時(shí)間:2024/3/26 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现打字机特效 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

該案例學(xué)習(xí)自B站UP主xiao-high

打印多條文段可以參考一下這里:傳送門(mén)。案例見(jiàn)博客個(gè)人簡(jiǎn)介的應(yīng)用,點(diǎn)這里看效果。(打印一段文字后,再打印一段,覆蓋前邊的內(nèi)容)

介紹

文本一個(gè)一個(gè)的顯示,同時(shí)有光標(biāo)閃爍效果。

點(diǎn)擊這里查看效果:傳送門(mén)

動(dòng)手制作

新建一個(gè)HTML文件。

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

body

添加一個(gè)div,class名為text,用于控制文本和光標(biāo)的大小。div內(nèi)部添加兩個(gè)span,分別作為文本和光標(biāo)的容器。光標(biāo)為符號(hào)|。

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

css

去除瀏覽器默認(rèn)的margin、padding值。

* {margin: 0;padding: 0; }

body設(shè)置讓div居中顯示,設(shè)置一個(gè)徑向漸變背景。

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

設(shè)置div內(nèi)的字體顏色為白色,字體大小在后邊js代碼中設(shè)置。

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

實(shí)現(xiàn)光標(biāo)閃爍

制作光標(biāo)閃爍動(dòng)畫(huà):動(dòng)畫(huà)設(shè)置兩幀,透明度從0到100。

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

光標(biāo)應(yīng)用該動(dòng)畫(huà),動(dòng)畫(huà)播放時(shí)間為0.5秒,線性播放,循環(huán)播放。同時(shí)設(shè)置左外邊距為5px。

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

script

參數(shù)說(shuō)明:

  • fontSize,字體大小
  • word,顯示文本的span標(biāo)簽
  • str,文本

在進(jìn)行繪制之前,我們需要確定打開(kāi)HTML文件的設(shè)備是pc還是手機(jī)。從而指定不同的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;//手機(jī)字體大小 }else{var fontSize = 28;//pc字體大小 }

設(shè)置文本大小

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

上邊的js代碼可以使用CSS中的@media 查詢來(lái)實(shí)現(xiàn),具體代碼如下:

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

font-size: 28px;

在前邊的css后邊再添加一個(gè)style標(biāo)簽,指定移動(dòng)端的字體大小。代碼如下:

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

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

添加要顯示的文本

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

通過(guò)class名選擇顯示文本的span標(biāo)簽

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

實(shí)現(xiàn)打字機(jī)效果

有了str和word我們就可以實(shí)現(xiàn)打字機(jī)效果了。將實(shí)現(xiàn)打字機(jī)效果封裝在一個(gè)方法內(nèi),方法名showText

//實(shí)現(xiàn)打字機(jī)效果 function showText() {}

我們定義幾個(gè)變量:

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

實(shí)現(xiàn)正放

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

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

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

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

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

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

所以實(shí)現(xiàn)正放代碼應(yīng)該為:

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

實(shí)現(xiàn)倒放

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

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

正/倒放結(jié)合

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

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

每隔一定的時(shí)間,這個(gè)時(shí)間我們可以通過(guò)str.length * time來(lái)計(jì)算,str.length * time為一次正放或倒放所用的時(shí)間,如果想讓正放倒放相隔一定的時(shí)間,我可以再添加一個(gè)等待時(shí)間,即前邊定義的timewait。

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

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

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

所以正/倒放結(jié)合完整代碼如下:

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

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

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

函數(shù)showText掩蓋bug后的完整代碼如下:

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

最后,我們需要調(diào)用一下這個(gè)函數(shù),才能使打字機(jī)效果生效。我這里是添加了一個(gè)定時(shí)器,頁(yè)面加載完成之后過(guò)1s再調(diào)用實(shí)現(xiàn)打字機(jī)效果的函數(shù)。代碼如下:

//打開(kāi)頁(yè)面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;/*讓光標(biāo)閃爍*/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; //手機(jī)字體大小} else {var fontSize = 28; //pc字體大小}//設(shè)置文本大小let textSize = document.querySelector('.text');textSize.style.fontSize = fontSize + "px";let str = "你好,我是輕率的保羅!很高興見(jiàn)到你!"; //要顯示的文本//獲取文本顯示的spanlet word = document.querySelector('.word');//打開(kāi)頁(yè)面1s后顯示文本setTimeout(showText, 1000);//實(shí)現(xiàn)打字機(jī)效果function showText() {let myflag = true;let time = 300; //每個(gè)字符顯示的時(shí)間let timewait = 2000; //正倒放等待時(shí)間for (let n = 1; n <= str.length; n++) { //正放setTimeout(function() { //定時(shí)器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() { //定時(shí)器word.innerHTML = str.substr(0, i);}, (i - 1) * time);}} else {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時(shí)器word.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}this.myflag = !this.myflag;}, str.length * time + timewait);}</script> </html>

修復(fù)bug

使用閉包來(lái)解決bug,詳細(xì)筆記訪問(wèn)這里。(這里的也是使用了閉包,不過(guò)定時(shí)器內(nèi)并沒(méi)有使用到外邊定義的標(biāo)志位myflag,函數(shù)定義的問(wèn)題。定時(shí)器內(nèi)的this.myflag不是外邊定義的myflag,而是匿名函數(shù)傳遞進(jìn)來(lái)的空值重新被后邊的this.myflag = !this.myflag;語(yǔ)句賦值了的定時(shí)器內(nèi)的局部變量,所以第一次沒(méi)有執(zhí)行if中的正放代碼是因?yàn)槠渲禐閚ull。解決方法是把定時(shí)器內(nèi)的匿名函數(shù)拿出來(lái),定時(shí)器內(nèi)調(diào)用函數(shù)名即可。)

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

修復(fù)bug

下邊的方法已經(jīng)廢棄,有了更好的實(shí)現(xiàn)方法。已放到上邊。這里的方法也可以實(shí)現(xiàn)效果,但是過(guò)于凌亂。

其實(shí)bug并沒(méi)有修復(fù),而是使用了另一種方法來(lái)實(shí)現(xiàn)打字機(jī)效果。將正、倒放單獨(dú)作為一個(gè)函數(shù),不過(guò)在正放的函數(shù)結(jié)束后調(diào)用倒放的函數(shù)。再使用一個(gè)函數(shù)調(diào)用正放的函數(shù)。

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

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

    • 正、倒放函數(shù)都是在正、倒放操作的基礎(chǔ)上加一個(gè)定時(shí)器,添加等待時(shí)間

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

      //正放 setTimeout(function() {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時(shí)器element.innerHTML = str.substr(0, i);}, (i - 1) * time);}//調(diào)用倒放setTimeout( 調(diào)用倒放 , 正放所用時(shí)間+等待時(shí)間 );}, timewait);//播放前的等待時(shí)間
  • 調(diào)用正放的函數(shù),showText02(element, str, num,time,timewait),形參有:顯示文本的容器,顯示的文本,播放次數(shù)(正+倒為一次),一個(gè)字符顯示時(shí)間,正倒放間隔時(shí)間

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

使用:

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

實(shí)現(xiàn)打字機(jī)效果的一些函數(shù):

//實(shí)現(xiàn)方法2 function showText02(element,str, num,time,timewait) {//time,每個(gè)字符顯示的時(shí)間,建議200毫秒//timewait,正倒放等待時(shí)間,建議2000毫秒//num,播放次數(shù),默認(rèn)一次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)控制播放次數(shù)setTimeout(function() {positive(element,str, time, timewait);}, (str.length * time * 2 + timewait*2) * i);//括號(hào)內(nèi)的時(shí)間為一次正加一次倒} } //正放 function positive(element,str, time, timewait) {setTimeout(function() {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時(shí)器element.innerHTML = str.substr(0, i);}, (i - 1) * time);}setTimeout(function() {reverse(element,str, time);}, str.length * time + timewait);//正放結(jié)束后再開(kāi)始倒放,使用定時(shí)器增加正放時(shí)間和結(jié)束后的等待時(shí)間}, timewait);//播放前的等待時(shí)間 } //倒放 function reverse(element,str, time, timewait) {setTimeout(function() {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時(shí)器element.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}, timewait);//使用定時(shí)器增加等待時(shí)間 }

完整源代碼如下:

<!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;/*讓光標(biāo)閃爍*/}@keyframes flash {from {opacity: 0;}to {opacity: 1;}}</style><style type="text/css">/*當(dāng)顯示設(shè)備為手機(jī)時(shí),字體大小設(shè)置為20px。(用于判斷設(shè)備類型的500px是一個(gè)經(jīng)驗(yàn)值)*/@media(max-width:500px) {.text {font-size: 20px;}}</style><script>let str = "你好,我是輕率的保羅!很高興見(jiàn)到你!"; //要顯示的文本//獲取文本顯示的span(顯示文本的容器)let word = document.querySelector('.word');//播放4次showText02(word,str,4);//顯示文本的容器,顯示的文本,播放次數(shù)(正+倒為一次),一個(gè)字符顯示時(shí)間,正倒放間隔時(shí)間//實(shí)現(xiàn)打字機(jī)效果(下邊為封裝的函數(shù))function showText02(element,str, num,time,timewait) {//time,每個(gè)字符顯示的時(shí)間,建議200毫秒//timewait,正倒放等待時(shí)間,建議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)控制播放次數(shù)setTimeout(function() {positive(element,str, time, timewait);}, (str.length * time * 2 + timewait*2) * i);//括號(hào)內(nèi)的時(shí)間為一次正加一次倒}}//正放function positive(element,str, time, timewait) {setTimeout(function() {for (let i = 1; i <= str.length; i++) { //正放setTimeout(function() { //定時(shí)器element.innerHTML = str.substr(0, i);}, (i - 1) * time);}setTimeout(function() {reverse(element,str, time);}, str.length * time + timewait);//正放結(jié)束后再開(kāi)始倒放,使用定時(shí)器增加正放時(shí)間和結(jié)束后的等待時(shí)間}, timewait);//播放前的等待時(shí)間}//倒放function reverse(element,str, time, timewait) {setTimeout(function() {for (let j = str.length; j >= 0; j--) { //倒放setTimeout(function() { //定時(shí)器element.innerHTML = str.substr(0, j);}, (str.length - j) * time);}}, timewait);//使用定時(shí)器增加等待時(shí)間}</script> </html>

原文鏈接:實(shí)現(xiàn)打字機(jī)特效

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。