var number = '1234567890'
var n = 0
var timerId = setInterval(()=>{
n++;
document.body.innerText = number.slice(0,n)
// 或者 document.body.innerText = number.substring(0,n)
if(n>=10){
clearInterval(timerId)
}
},500)
複製代碼
假設有 10 個數字,初始時 n = 0,屏幕上一個數字都沒有,每隔 500 ms多出現一個數,用 setInterval 來作定時,用 slice 或 substring 控制多出現的數,當 n ≥ 10 時 ,說明數字已經所有出現,clearInterval。 css
若是我想寫每隔 500ms 打印的是 CSS 語句怎麼辦?面試
var content = `body{
background:red
}`
var n = 0
var timerId = setInterval(()=>{
n++;
document.body.innerText = content.slice(0,n)
if(n>=content.length){
clearInterval(timerId)
}
},200)
複製代碼
打印出來怎麼是這個效果?background 前面的的縮進怎麼消失了?由於 HTML 會把大於等於兩個的空格或者縮進都變成一個空格。bash
解決app
在 CSS 中有一個 <pre> </pre>
標籤,pre 是 preview 預覽的意思。在頁面中加一個 <pre> </pre>
標籤。dom
HTML異步
<body>
<pre id="code"></pre>
</body>
複製代碼
CSS函數
var content = `body{
background:red;
}`
var n = 0
var timerId = setInterval(()=>{
n++;
code.innerText = content.slice(0,n)
if(n>=content.length){
clearInterval(timerId)
}
},100)
複製代碼
效果 flex
寫進去的代碼怎麼生效呢?個人背景並無變成紅色。優化
解決動畫
當頁面中動態的 CSS 代碼寫完的時候,同時在 <style>
標籤中加一樣一句話,這樣就好像是寫的代碼生效了。
HTML
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style id="styleTag"></style>
</head>
<body>
<pre id="code"></pre>
</body>
複製代碼
在 head 裏給 style 一個 id。
CSS
var content = `body{
background:red;
}`
var n = 0
var timerId = setInterval(()=>{
n++;
code.innerText = content.slice(0,n)
if(n>=content.length){
styleTag.innerText = content
clearInterval(timerId)
}
},1000)
複製代碼
var content = `
面試官你好,我是XXX
只用文字做作我介紹太單調了
我就用代碼來介紹吧
首先準備一些樣式
body{
background:red;
}`
var n = 0
var timerId = setInterval(()=>{
n++;
code.innerText = content.slice(0,n)
if(n>=content.length){
styleTag.innerText = content
clearInterval(timerId)
}
},100)
複製代碼
問題
誒???CSS 樣式怎麼不生效了?
緣由
由於<style>
的標籤裏有文字,CSS 沒有辦法解析代碼,顯示樣式。
解決
以註釋的形式添加文字。
var content = `
/*
* 面試官你好,我是XXX
* 只用文字做作我介紹太單調了
* 我就用代碼來介紹吧
* 首先準備一些樣式
*/
body{
background:red;
}`
var n = 0
var timerId = setInterval(()=>{
n++;
code.innerText = content.slice(0,n)
if(n>=content.length){
styleTag.innerText = content
clearInterval(timerId)
}
},100)
複製代碼
CSS
*{
transition: all 1s;
}
複製代碼
#code{
border:1px solid red;
padding:16px;
}
複製代碼
原理
偷樑換柱
var timerId = setInterval(() => {
n++;
code.innerText = content.slice(0, n)
code.innerText = code.innerText.replace('body','<span style="color:red">body</span>')
if (n >= content.length) {
styleTag.innerText = content
clearInterval(timerId)
}
}, 100)
複製代碼
利用 span 標籤樣式,替換沒有樣式的 CSS。
注意:若是想要識別替換的標籤生效,須要把 innerText 改爲 innerHTML,對比結果以下。
var n = 0
var timerId = setInterval(() => {
n++;
code.innerHTML = content.slice(0, n)
code.innerHTML = code.innerHTML.replace('body','<span style="color:red">body</span>')
if (n >= content.length) {
styleTag.innerText = content
clearInterval(timerId)
}
}, 100)
複製代碼
思考
難道我要所有手寫一遍高亮語法替換?
解決
調用別人的庫 Prism ,引入 CSS 和 JavaScript。
code.innerHTML =
code.innerHTML.replace('body','<span style="color:red">body</span>')
複製代碼
調用庫函數來實現高亮,這個庫的原理就是加 span 標籤來實現高亮
code.innerHTML =
Prism.highlight(code.innerHTML, Prism.languages.css, 'css');
複製代碼
再次偷樑換柱
讓別人覺得這個高亮是由於我寫了高亮這部分的代碼而實現的
解決
庫裏的高亮選擇器如上圖,這就提示咱們能夠經過覆蓋再復原來實現。注意
CSS 引入的順序,用本身寫的樣式去覆蓋庫裏的樣式。
<link rel="stylesheet" href="vendor/prism/prism.css">
<link rel="stylesheet" href="css/default.css">
複製代碼
default.css
.token.selector{
color: black;
}
.token.property{
color: black;
}
複製代碼
JavaScript
/* 給代碼加個高亮吧 */
.token.selector{
color: #690;
}
.token.property{
color: #905;
}
複製代碼
這樣就讓別人感受是由於高亮部分的代碼使屏幕中顯示的代碼高亮了。
/* 加點 3D 效果 */
#code{
transform: rotate(360deg);
}
複製代碼
function fn2() {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
}
function fn3(preContent) {
var contentPaper = `
#paper{
width:100px;
height:100px;
background:red;
}
`
var n = 0
var timerId = setInterval(() => {
n++;
code.innerHTML = preContent + contentPaper.substring(0, n)
code.innerHTML =
Prism.highlight(code.innerHTML, Prism.languages.css, 'css');
styleTag.innerText = preContent + contentPaper.substring(0, n)
if (n >= contentPaper.length) {
clearInterval(timerId)
}
}, 10)
}
複製代碼
在第一個 clearInterval 後執行 fn2 和 fn3。
var content = `...註釋暫時省略...`
var n = 0
var timerId = setInterval(() => {
n++;
code.innerHTML = content.slice(0, n)
code.innerHTML =
Prism.highlight(code.innerHTML, Prism.languages.css, 'css');
styleTag.innerText = content.slice(0, n)
if (n >= content.length) {
clearInterval(timerId)
fn2()
fn3(content)
}
}, 10)
複製代碼
注意
要把 content 的內容傳給 fn3 ,不然 fn3 內容會覆蓋前面的效果,而不是追加在後。
糾正一個 bug
styleTag.innerText = content.slice(0, n)
替換 styleTag.innerText = content
前一句表示一邊寫代碼一遍展現效果,後一句表示當全部的樣式代碼寫完以後才添加進來,這樣展現的效果有延遲。
效果
代碼優化
var content = `
/*
* 面試官你好,我是XXX
* 只用文字做作我介紹太單調了
* 我就用代碼來介紹吧
* 首先準備一些樣式
*/
*{
transition: all 1s;
}
body{
background:#eee;
}
#code{
border:1px solid red;
padding:16px;
}
/* 給代碼加個高亮吧 */
.token.selector{
color: #690;
}
.token.property{
color: #905;
}
/* 加點 3D 效果 */
#code{
transform: rotate(360deg);
}
/* 接下來我須要一張白紙 */
`
var contentPaper = `
#paper{
width:100px;
height:100px;
background:red;
}`
writeCode('', content, () => {
createPaper(() => {
writeCode(content, contentPaper)
})
})
function writeCode(prefix, code, fn) {
let domCode = document.querySelector('#code')
domCode.innerHTML = prefix || ''
let n = 0
let timerId = setInterval(() => {
n++;
domCode.innerHTML =
Prism.highlight(prefix + code.substring(0, n),
Prism.languages.css, 'css');
styleTag.innerHTML = prefix + code.substring(0, n)
if (n >= code.length) {
clearInterval(timerId)
fn().call()
}
},50)
}
function createPaper(fn) {
var paper = document.createElement('div')
paper.id = 'paper'
document.body.appendChild(paper)
fn.call()
}
複製代碼
若是不使用,執行順序:
這是異步啊,emmmm,什麼是異步?
生活中的例子:
同步:讓黃牛去買票,而後我站着等。
異步:讓黃牛去買票(告訴黃牛買到票就打電話給我),而後我去作別的事。
異步:不等結果,直接進行下一步。
這時能夠採用回調來解決,回調是拿到異步結果的一種方式。回調也能夠拿同步結果。
最開始 domCode 裏面存的是空字符串,一邊寫樣式一邊存第一次樣式代碼,接下來建立 paper 的 div,建立完成後繼續寫樣式,是在第一次的樣式上追加,不然第二次樣式覆蓋第一次樣式代碼。
default.css
#code{
height: 100vh;
overflow: hidden;
}
複製代碼
在 writeCode( ) 的styleTag.innerHTML
下面加 domCode.scrollTop = domCode.scrollTop = domCode.scrollHeight
,只要高度變高了,能拉多長拉多長。
styleTag.innerHTML = prefix + code.substring(0, n)
domCode.scrollTop = domCode.scrollTop = domCode.scrollHeight
複製代碼
JavaScript
function createPaper(fn) {
var paper = document.createElement('div')
paper.id = 'paper'
var content = document.createElement('pre')
content.className = 'content'
paper.appendChild(content)
document.body.appendChild(paper)
fn.call()
}
/* 接下來我須要一張白紙 */
#code{
position: fixed;
left: 0;
width: 50%;
height: 100%;
}
#paper{
padding: 16px;
position: fixed;
right: 0;
width: 50%;
height: 100%;
background: #ddd;
display: flex;
justify-content: center;
align-items: center;
}
#paper > content {
background: white;
width: 100%;
height: 100%;
}
複製代碼