如何在頁面中一個一個的出現10個數,從0到9?從最簡單的開始javascript
連接css
=> 稍加改進html
連接java
=> 把result 改成cssweb
連接面試
=> 一個問題:html會忽略全部的空格和回車變成一個空格,解決辦法,用pre標籤包起來ajax
連接promise
=> 代碼雖然寫到頁面上了,可是沒有生效,解決辦法,除了在pre裏面寫result,同時在style標籤裏也寫一份resultbash
連接app
到這路爲止,思路就通了,咱們能夠在頁面中也任何css代碼而且生效,code裏面的代碼是往頁面中添加內容,style中的代碼是給頁面中的內容添加樣式
=> 給頁面中添加一些內容
但這是這樣寫,就同時往style標籤裏寫文字了,怎麼辦?把文字用註釋標記起來。那麼又如何讓代碼高亮?好比:將html代碼高亮爲紅色怎麼辦?有一個辦法就是給這個html加上一個span標籤,而後給sapn標籤上加上內聯樣式。爲何不能在style標籤中去控制呢?選不到html這個文本,style只能操做標籤。那能夠<span style="color:red">html</span>
這樣嗎?這樣是能夠,可是有沒有想過style標籤你怎麼能夠加標籤呢?那怎麼辦呢?咱們能夠在code.innerHTML以後作一下替換
pre標籤裏還能夠有標籤,並且這些標籤是不會當作頁面內容去展現的,只會把他們當作html標籤
如今咱們知道只須要給須要高亮的代碼添加一個span標籤再添加一個行內樣式便可,那咱們得經過正則去分析哪些是選擇器,很麻煩,可是不用擔憂,開源世界確定已經解決了這個問題,谷歌:js Syntax Highlight,會有一個Prism.js它能把一個字符串的關鍵字加上span
凡是用到別人的東西,就用CRM套路
文檔中說明,若是要使用Prism就要引入它的css和js
下載最小版,往下滾動有個下載js文件和下載css文件
根據文檔知:咱們只要在項目裏引入了Prism.js和Prism.css2個文件,而後在main.js里加上:
var text = "html{background: rgb(222,222,222);font-size: 16px;}"
var css = Prism.highlight(x, Prism.languages.javascript, 'javascript');
console.log(css)
複製代碼
咱們就會發先每一個字符串都被加上了span標籤
讓代碼高亮的代碼:
var n = 0
var id = setInterval(()=>{
n+=1
code.innerHTML = result.substring(0,n)
code.innerHTML = Prism.highlight(code.innerHTML, Prism.languages.css);
style.innerHTML = result.substring(0,n)
if(n >= result.length){
window.clearInterval(id)
}
},10)
複製代碼
爲了顯示出高的b格,咱們能夠在style.css裏用黑色先覆蓋以前代碼高亮,而後再在#style裏把原來代碼高亮的顏色找回來再覆蓋上去,而後說:‘我須要一點代碼高亮’
css代碼:
breathe-div {
width: 50%;
height: 50%;
margin: 26px;
border: 1px solid #2b92d4;
cursor: pointer;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: breathe;-webkit-animation-duration: 1500ms;
-webkit-animation-iteration-count: infinite;-webkit-animation-direction: alternate;
}
@-webkit-keyframes breathe {
0% {
opacity: .4;
box-shadow: 0 1px 2px rgba(0, 147, 223, 0.4), 0 1px 1px rgba(0, 147, 223, 0.1) inset;
}
100% {
opacity: 1;
border: 1px solid rgba(59, 235, 235, 0.7);
box-shadow: 0 1px 30px #0093df, 0 1px 20px #0093df inset;
}
}
複製代碼
html代碼:
<pre id='code' class="breathe-div"></pre>
複製代碼
#code{
-webkit-transform: translateX(0%) rotateX(15deg) rotateY(15deg);
margin: 25px;
}
複製代碼
//css
.breathe-div {overflow-y: scroll;}
//js
code.scrollTop = code.scrollHeight;
複製代碼
function fn2() {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
}
複製代碼
因爲是追加內容因此不能是下面的代碼,不然就把以前的全部內容都覆蓋了
code.innerHTML = result.substring(0, n)
複製代碼
應該是追加,是下面這樣嗎
code.innerHTML = code.innerHTML + result.substring(0, n)
複製代碼
這樣也不對,這樣每次不是一隻添加一個字符,而是基於上次的添加,不該該每次都從0開始,而是應該從n-1開始,每次只添加一個字符:
code.innerHTML = code.innerHTML + result.substring(n-1, n)
複製代碼
合併以後的寫法:
code.innerHTML = Prism.highlight(code.innerHTML + result.substring(n-1, n), Prism.languages.css)
複製代碼
這樣寫發現有bug,由於以前的code裏面的代碼是已經被span包裹了(Prism作的事情),如今等於又加了一層span,怎麼辦呢,就是在調用fn3的時候,拿到以前的結果result並傳進去,fn3用preResult接收,由於以前的結果result是沒有span標籤包裹的,這樣Prism就能夠對以前的內容加上如今追加的內容一塊兒加上span並給予代碼高亮
var n = 0
var id = setInterval(() => {
n += 1
code.innerHTML = result.substring(0, n)
code.innerHTML = Prism.highlight(code.innerHTML, Prism.languages.css);
style.innerHTML = result.substring(0, n)
if (n >= result.length) {
window.clearInterval(id)
fn2()
fn3(result)
}
code.scrollTop = code.scrollHeight;
}, 1)
function fn2() {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
}
function fn3(preResult) {
var result = `#paper{width: 200px;height: 200px;background: red;}
`
var n = 0
var id = setInterval(() => {
n += 1
code.innerHTML = code.innerHTML + result.substring(n-1, n)
code.innerHTML = Prism.highlight(preResult + result.substring(0, n),
Prism.languages.css);
style.innerHTML = preResult+ result.substring(0, n)
if (n >= result.length) {
window.clearInterval(id)
}
})
}
複製代碼
style.innerHTML = preResult+ result.substring(0, n)
複製代碼
// main.js
var result = `/*面試官你好,我是xxx
我將以動畫的形式介紹本身
只用文字的形式太單調了
我就用代碼來介紹吧
首先準備一些樣式
*/
*{padding: 0; margin: 0;transition: all 1s;}
html{background: #1F2242;
font-size: 16px;
}
#code{background:#303030;
width: 50%;
border: 1px solid #2b92d4;
padding: 16px;
}
/*我須要一點代碼高亮*/
#code{color: #75C732;}
.token.selector{color: #C39745}
.token.punctuation{color: rgba(255,255,255,.4)}
.token.property{color: #23E5E3};
.token.function{color: #EF2C1B}
/*內容多了,來個滾動條吧*/
.breathe-div {overflow-y: scroll;}
/*來點呼吸燈的效果吧*/
.breathe-div {
width: 50vw;
height: 80vh;
border: 1px solid #2b92d4;
cursor: pointer;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: breathe;
-webkit-animation-duration: 1500ms;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
}
@-webkit-keyframes breathe {
0% {
opacity: .5;
box-shadow: 0 1px 20px rgba(0, 147, 223, 0.4), 0 1px 1px rgba(0, 147, 223, 0.1) inset;
}
100% {
opacity: 1;
border: 1px solid rgba(59, 235, 235, 0.7);
box-shadow: 0 1px 15px #0093df, 0 1px 10px #0093df inset;
}
}
/*來點動畫效果吧*/
#code{
-webkit-transform: rotateX(15deg) rotateY(15deg);
margin: 25px;
}
/*下面請容許我介紹一下本身*/
/*我須要一張白紙*/
`
var n = 0
var id = setInterval(() => {
n += 1
code.innerHTML = result.substring(0, n)
code.innerHTML = Prism.highlight(code.innerHTML, Prism.languages.css);
style.innerHTML = result.substring(0, n)
if (n >= result.length) {
window.clearInterval(id)
fn2()
fn3(result)
}
code.scrollTop = code.scrollHeight;
}, 1)
function fn2() {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
}
function fn3(preResult) {
var result = ` #paper{width: 200px;height: 200px;background: red;}
`
var n = 0
var id = setInterval(() => {
n += 1
code.innerHTML = code.innerHTML + result.substring(n-1, n)
code.innerHTML = Prism.highlight(preResult + result.substring(0, n), Prism.languages.css);
style.innerHTML = preResult+ result.substring(0, n)
if (n >= result.length) {
window.clearInterval(id)
}
})
}
// style.css
.token.selector{color: black}
.token.punctuation{color: black}
.token.property{color: black}
.token.function{color: #AB2B9A}
//html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./vendor/prism/prism.css">
<link rel="stylesheet" href="./css/style.css">
<style id = 'style'></style>
</head>
<body>
<pre id='code' class="breathe-div"></pre>
<script src="./vendor/prism/prism.js"></script>
<script src="./js/main.js"></script>
</body>
</html>
複製代碼
把類似的代碼寫成一個函數
函數fn2()和函數fn3()不屬於函數writeCode的邏輯,它們要調,讓它們本身調也就是後面說的回調
下面看一個問題:先往#code裏面寫代碼然writeCode()後就再準備paper調用fn2()能夠這樣寫嗎?
writeCode(result)
console.log('開始執行fn2'); fn2()
/*將code寫到#code和style標籤裏 */
function writeCode(code) {
let domCode = document.querySelector('#code')
let n = 0
console.log('設置鬧鐘')
let id = setInterval(() => {
console.log('開始寫代碼')
n += 1
domCode.innerHTML = Prism.highlight( code.substring(0, n), Prism.languages.css);
style.innerHTML = code.substring(0, n)
domCode.scrollTop = domCode.scrollHeight;
if (n >= result.length) {
window.clearInterval(id)
}
}, 1)
}
function fn2() {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
}
function fn3(preResult) {
var result = ` #paper{width: 200px;height: 200px;background: red;} `
}
複製代碼
不行,由於writeCode()是定鬧鐘執行的
writeCode(),至關於如今不是當即執行全部代碼,而是定個鬧鐘50毫秒以後開始寫第一行代碼, 世界上writeCode()作了這麼幾件事:
1.定鬧鐘,鬧鐘定完就結束了,鬧鐘裏面的代碼尚未被調,何時會被調?10毫秒以後 2.writeCode返回 3.執行fn2() 4.鬧鐘時間到 5.執行鬧鐘裏面的代碼,也就是往#code裏寫第一行代碼
咱們經過打log便知道真正的順序
fn2會在寫代碼以前就已經執行了,也就是尚未往#code裏面寫代碼,頁面的paper已經準備好了,這不是咱們想要的,咱們想要的是等咱們把code都寫到#code裏面以後纔出現paper,咱們想要的之心順序是,往#code裏面把代碼寫完再調用fn2(),就比如是:
定鬧鐘明天早上6點起牀() 玩遊戲()
是先玩遊戲仍是先起牀?固然是先玩遊戲,再起牀
上面的函數writeCode就是一個異步的操做,由於咱們再它尚未寫完代碼就當即執行了函數fn2
劃重點:異步就是不等結果,直接進行下一步,理解異步的精髓就是【不等結果】
那怎麼解決上面的問題呢? 得經過回調來解決
再以買黃牛票爲例子:
有2種情景:
1.讓黃牛去買票,而後本身站着等(同步的過程) 2.讓黃牛去買票(告訴黃牛,你買到票就call我),而後本身去作別的
同步的過程就是我必定要等到這個解結果,不然我就不吃飯不睡覺 而異步就是我不等結果,我先去作別的事情
精髓就是: 等結果就會同步,不等結果就是異步
你是選擇哪種?固然是選擇第二種
同步的好處就是必定能拿到結果可是效率會很低 異步的好處就是效率很高,可是當時是拿不到結果的(那怎麼辦?咱們須要把回調放到異步裏),得等回調函數執行了,才能拿到結果
既然異步就是不等結果,那若是這個結果是咱們想要的結果,咱們該如何拿到這個結果?我想知道writeCode何時結束,咱們怎麼知道?有一個辦法回調能夠
劃重點: 回調能夠拿到異步的結果,也能夠拿到同步的結果,也就是說異步和回調能夠同時出現,也能夠不一樣時出現,每每異步會和回調同時出現,可是不表明它們2是同一種東西,不少人搞不清楚什麼是異步什麼是回調,有的人把異步當成回調,也有人把回調當異步
異步的關鍵詞:不等結果; 回調的關鍵詞: 拿到異步結果的一種方式
若是不想等結果,可是以後又向拿到結果怎麼辦?答案是用回調,(告訴黃牛,你買到票就call我)這就至關於回調
劃重點: 回調是拿到異步結果的一種方式,可是注意回調也能夠拿同步的結果
把:告訴黃牛,你買到票就call我,這句話翻譯成英文就是:when you get the ticket call me back, 回到的callback就是這麼來的,由於異步的時候就至關於失去了聯繫,只能讓黃牛拿到票的時候給咱們回電話
writeCode(result, () => {
createPaper() // 至關於黃牛回電話說買到票了
})
/*將code寫到#code和style標籤裏 */
function writeCode(code, callback) {
let domCode = document.querySelector('#code')
let n = 0
let id = setInterval(() => {
n += 1
domCode.innerHTML = Prism.highlight(code.substring(0, n), Prism.languages.css);
style.innerHTML = code.substring(0, n)
domCode.scrollTop = domCode.scrollHeight;
if (n >= result.length) {
window.clearInterval(id)
callback.call() // 這裏就至關於給黃牛打電話問是否買到票
}
}, 1)
}
function createPaper() {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
}
function fn3(preResult) {
var result = ` #paper{width: 200px;height: 200px;background: red;} `
}
複製代碼
問題來了函數createPaper是異步的函數同步的? 就得看它是等結果仍是不等結果,很明顯這裏沒有關於等的代碼(如定鬧鐘),都是平鋪直敘的因此是同步的,同步的代碼也能夠加回調,我麼能夠往createPaper()再加回調函數createPaper也就是繼續往頁面中添加內容
writeCode是會覆蓋以前的代碼的有沒有辦法不覆蓋?
writeCode(result, () => {
createPaper(()=>{
writeCode() // writeCode是會覆蓋以前的代碼的有沒有辦法不覆蓋
})
})
/*將code寫到#code和style標籤裏 */
function writeCode(code, callback) {
let domCode = document.querySelector('#code')
let n = 0
let id = setInterval(() => {
n += 1
domCode.innerHTML = Prism.highlight(code.substring(0, n), Prism.languages.css);
style.innerHTML = code.substring(0, n)
domCode.scrollTop = domCode.scrollHeight;
if (n >= result.length) {
window.clearInterval(id)
callback.call()
}
}, 1)
}
function createPaper(callback) {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
callback()
}
function fn3(preResult) {
var result = ` #paper{width: 200px;height: 200px;background: red;} `
}
複製代碼
告訴咱們一個以前的代碼是什麼,加一個前綴,prefix, prefix爲以前往#code裏面寫的內容,第一次writeCode的時候prefix爲空字符換,由於此時尚未往#code裏面添加內容
var result2 = ` #paper{width: 200px;height: 200px;background: red;} `
writeCode('',result, () => { // 第一次writeCode的時候prefix爲空字符換,由於此時尚未往#code裏面添加內容
createPaper(()=>{
writeCode(result,result2)
})
})
/*將code寫到#code和style標籤裏 */
function writeCode(prefix,code, callback) { // prefix爲以前往#code裏面寫的內容
let domCode = document.querySelector('#code')
domCode.innerHTML = prefix || ''
let n = 0
let id = setInterval(() => {
n += 1
domCode.innerHTML = Prism.highlight(prefix + code.substring(0, n), Prism.languages.css);
style.innerHTML = prefix + code.substring(0, n)
domCode.scrollTop = domCode.scrollHeight;
if (n >= code.length) {
window.clearInterval(id)
callback.call()
}
}, 1)
}
function createPaper(callback) {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
callback()
}
複製代碼
看一下代碼的邏輯:
writeCode('',result, () => {
createPaper(()=>{
writeCode(result,result2)
})
})
複製代碼
先去執行writeCode往頁面#code中添加n內容,等writeCode執行完了以後再執行createPaper即建立一張紙,等createPaper執行完了後再執行writeCode往#code裏面一行一行的添加內容,writeCode(result,result2)
這裏的result必需要有,這是#code以前的全部內容必需要有,result2是基於result再往裏面添加內容
再來講下什麼是異步:
function 異步作事(){
setTimeout(function(){
console.log('異步作事')
},1000)
}
function 同步作事(){
console.log('同步作事')
}
異步作事()
console.log(1)
// 因爲異步作事,不等結果,因此先打1
同步作事()
console.log(1)
// 因爲同步作事,等結果,全部要等作完事再執行1
// 若是是作完事再打1就是同步
// 若是事沒作完就打1就是異步
複製代碼
注意: 異步是拿不到結果的
var promise = $.get('./xxxx')
promise.then(success,fail)
複製代碼
ajax是異步的,不等結果,直接進行下一步,n秒後拿到結果,promise不是結果而是一個承諾,承諾會拿到結果但不是如今,若是承諾兌現了就執行success,若是承諾沒有執行就調fail,Promise就像打的白紙借條