專案介紹
一個可以自動播放書寫過程簡歷,主要運用原生JS和CSS3的知識點。
用到的庫:
相關連結
設計過程
基本思想—動起來
-
想辦法讓文字逐個出現在頁面中
setTimeout(()=>{ document.body.innerHTML='1' },1000) setTimeout(()=>{ document.body.innerHTML='2' },2000) setTimeout(()=>{ document.body.innerHTML='3' },3000) 複製程式碼
-
成功了,但是有點傻,為何我們不試一試
setInterval
加上slice()
或者substring()
var result = '1234567890' var n = 0 setInterval(()=>{ n += 1 document.body.innerHTML = result.substring(0,n) },500) 複製程式碼
slice()
和substring()
的區別是,substring()
不接受負的引數 -
既要開始,也要結束。想辦法取消鬧鐘
var result = '1234567890' var n = 0 var clock = setInterval(()=>{ n += 1 document.body.innerHTML = result.substring(0,n) if(n>=result.length){ window.clearInterval(clock) } },500) 複製程式碼
換成CSS
-
將內容換成CSS
var result = ` body{ background:green; } ` var n = 0 var clock = setInterval(()=>{ n += 1 document.body.innerHTML = result.substring(0,n) if(n>=result.length){ window.clearInterval(clock) } },500) 複製程式碼
執行一下。黑人問號臉——我的換行沒啦???
這是因為在HTML裡面,連續出現多個看不見的字元,瀏覽器會認為它是一個空格
-
利用
<pre>
標籤HTML
<pre>
元素表示預定義格式文字。在該元素中的文字通常按照原檔案中的編排,以等寬字型的形式展現出來,文字中的空白符(比如空格和換行符)都會顯示出來。HTML中加入
<pre>
標籤,將內容寫到<pre>
中<body> <pre id="code"></pre> </body> 複製程式碼
var result = ` body{ background:green; } ` var n = 0 var clock = setInterval(()=>{ n += 1 code.innerHTML = result.substring(0,n) if(n>=result.length){ window.clearInterval(clock) } },100) 複製程式碼
-
應用程式碼
現在我們只是將程式碼展示了出來,但是看到效果,所以我們要將程式碼寫入到
<style>
中<head> <style id="myStyle"></style> </head> <body> <pre id="code"></pre> </body> 複製程式碼
var result = ` body{ background:green; } ` var n = 0 var clock = setInterval(()=>{ n += 1 code.innerHTML = result.substring(0,n) myStyle.innerHTML = result.substring(0,n) if(n>=result.length){ window.clearInterval(clock) } },500) 複製程式碼
完善細節
-
沒效果?因為文字也寫了進去
解決辦法-將除去CSS內容進行註釋
/*你好,我是不遠,一名前端工程師。 請允許我做一個簡單的自我介紹,但是文字太單調,所以我想來點特別的。 首先我準備一下樣式。 */ *{ transition: all 1s; } html{ background:#363636 color:#fff; font-size:16px; } 複製程式碼
-
程式碼高亮? 首先會想到這樣去解決,
<span style="color":red;>html</span> 複製程式碼
但是在CSS中這樣的語法是不允許的。
- 方法一:偷樑換柱
var n = 0 var clock = setInterval(()=>{ n += 1 code.innerHTML = result.substring(0,n) code.innerHTML = code.innerHTML.replace('html','<span style="color:red;">html</span>') myStyle.innerHTML = result.substring(0,n) if(n>=result.length){ window.clearInterval(clock) } },500) 複製程式碼
但是,很傻,很累,好的程式設計師要學會偷懶
-
方法二:prism.js 引入prism官網的JS和CSS檔案後
var n = 0 var clock = setInterval(() => { n += 1 code.innerHTML = result.substring(0, n) code.innerHTML = Prism.highlight(code.innerHTML, Prism.languages.css) //修改code為prism提供的樣式 myStyle.innerHTML = result.substring(0, n) if (n >= result.length) { window.clearInterval(clock) } }, 50) 複製程式碼
-
程式碼高亮變化 我們需要讓程式碼預設是平平無奇的樣子,然後再增加高亮效果。這樣活增加視覺的觀賞性。
-
設定預設樣式 我們需要在html中引入一個預設樣式的css檔案,內容是對程式碼的預設樣式設定。
.token.selector{ color: black; } .token.property{ color: black; } .token.punctuation{ color: black; } 複製程式碼
-
設定高亮樣式
.token.selector{ color: #a6e22e; } .token.property{ color: #f92672; } .token.punctuation{ color: #f8f8f2; } 複製程式碼
-
注意一:上面類的名稱是根據prism提供的來的,審查元素可以看到名稱
-
注意二:CSS檔案應放在引入的prism樣式的下面,以免被覆蓋
-
加入html元素
-
CSS執行結束,執行第二個函式,控制html;第三個函式控制html樣式
var n = 0 var clock = setInterval(() => { //原始碼不變 if (n >= result.length) { window.clearInterval(clock) fn2() fn3() } }, 10) 複製程式碼
-
定義fn2()
function fn2(){ var paper = document.createElement('div') paper.id = 'paper' document.body.appendChild(paper) } 複製程式碼
-
定義fn3()做一個左右結構,執行fn3(){}
function fn3(preResult) { var result = ` #paper{ width:200px; height:400px; background:#F1E2C3; } ` var n = 0 var clock = setInterval(() => { n += 1 code.innerHTML = preResult + result.substring(0, n) code.innerHTML = Prism.highlight(code.innerHTML, Prism.languages.css) myStyle.innerHTML = preResult + result.substring(0, n) if (n >= result.length) { window.clearInterval(clock) } }, 10) } 複製程式碼
封裝函式
- 封裝函式
/*把code寫到#code和style標籤裡面*/
function writeCode(code){
let domCode = document.querySelector('#code')
let n = 0
var clock = setInterval(() => {
n += 1
domCode.innerHTML = Prism.highlight(code.substring(0, n), Prism.languages.css)
myStyle.innerHTML = code.substring(0, n)
if (n >= code.length) {
window.clearInterval(clock)
}
}, 10)
}
//封裝
var result = `......`
writeCode(cssCode)
//呼叫(原result內容)
複製程式碼
-
回撥函式
封裝完畢後,當我們想緊接呼叫
f2()
時,又尷尬了。因為setInterval()
是一個鬧鐘(非同步),所以在設定好鬧鐘之後,就會立即執行f2()
,可是正確的執行邏輯是在code
寫完之後再呼叫f2()
-
不等結果就是非同步
-
回撥是拿到非同步結果的一種方式(也可以拿到同步結果)
-
-
防止覆蓋之前的程式碼,我們增加一個引數
prefix
function writeCode(prefix,code,fn){ //.... } }, 10) } 複製程式碼
-
呼叫函式
第一次呼叫的時候由於之前沒有內容,所以我們
prefix
為''
function writeCode(prefix, code, fn) { let domCode = document.querySelector('#code') let n = 0 var clock = setInterval(() => { n += 1 domCode.innerHTML = Prism.highlight(prefix + code.substring(0, n), Prism.languages.css) myStyle.innerHTML = prefix + code.substring(0, n) if (n >= code.length) { window.clearInterval(clock) fn.call() } }, 10) } 複製程式碼
呼叫函式
writeCode('', cssCode, () => { createPaper(() => { writeCode(cssCode, htmlCode) }) }) 複製程式碼
繼續優化細節
-
優化程式碼展示視窗,使其和展示視窗一樣高;在defulf.css裡設定為
#code{ height: 100vh; overflow: hidden; } 複製程式碼
-
自動滾動程式碼至底部,再封裝的函式內增加程式碼
function writeCode(prefix, code, fn) {
//...
domCode.scrollTop=domCode.scrollHeight
//...
}, 10)
}
複製程式碼
Element.scrollTop
屬性可以獲取或設定一個元素的內容垂直滾動的畫素數。
-
scrollIntoView()
方法:如果展示視窗設定的是
overflow: auto;
或者overflow: scroll;
會自動拉到底部Element.scrollIntoView(false) 複製程式碼
element.scrollIntoView(false)
為滾動至底部element.scrollIntoView(true)
為滾動至頂部其他引數:
-
behavior
可選定義緩動動畫,
"auto"
,"instant"
, 或"smooth"
之一。預設為"auto"
。 -
block
可選"start"
,"center"
,"end"
, 或"nearest"
之一。預設為"center"
。 -
inline
可選"start"
,"center"
,"end"
, 或"nearest"
之一。預設為"nearest"
。element.scrollIntoView({behavior: "instant", block: "end", inline: "nearest"}); 複製程式碼
-
增加簡歷展示頁
編寫JS增加編寫簡歷內容的展示視窗。與程式碼展示視窗類似
function writeMarkdown(markdown, fn) {
let domPaper = document.querySelector('#paper')
let n = 0
var clock = setInterval(() => {
n += 1
domPaper.innerHTML = Prism.highlight(markdown.substring(0, n), Prism.languages.markdown)
domPaper.scrollIntoView({behavior: "instant", block: "end", inline: "nearest"})
if (n >= markdown.length) {
window.clearInterval(clock)
fn.call()
}
}, 10)
複製程式碼
變成markdown語法
利用第三方庫**marked.js**
document.querySelector('#paper').innerHTML = marked(markdown)
fn.call()
}
複製程式碼
寫到這裡基本就結束了,剩下的就是非同步函式呼叫的順序了。然後再慢慢的修改CSS樣式。就可以大工完成了
——遠方不遠