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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

javascript --- [虚拟DOM] 初始化 实现

發(fā)布時間:2023/12/10 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 javascript --- [虚拟DOM] 初始化 实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

說明

  • 本篇主要說明為什么要使用虛擬DOM技術(shù),以及如何實現(xiàn)簡單的虛擬dom
  • 您將會學(xué)到:
    1.原生JS對DOM的操作
    2.虛擬DOM的相關(guān)概念
    3.DIFF算法的基礎(chǔ)概念

為什么提出 -> DOM操作慢

  • 我們使用createElement屬性來創(chuàng)建一個最常見的div,看看一個最常見的DOM有多少個屬性
<script>const div = document.createElement('div');let str = '';for(let key in div){str += key + ' ';}console.log(str); </script>

  • 可以看出,每個DOM其實是由很多內(nèi)置的屬性.因此,當(dāng)DOM元素的操作過多的時候,其性能可想而知.
  • 這就迫使我們?nèi)ハ胍粋€辦法去減少DOM操作

為什么提出 -> 對比Ajax技術(shù)的出現(xiàn)

  • 早期的網(wǎng)頁交互,是整個頁面進行更新的.
  • 但是大多數(shù)時候,用戶對頁面的操作,只是一小部分,這就導(dǎo)致了大多數(shù)更新是多余的.
  • 于是產(chǎn)生了Ajax技術(shù)(網(wǎng)頁的部分更新)
  • 可以模仿Ajax技術(shù),去部分渲染DOM

為什么提出 -> DOM樹的概念

  • 你可以會反駁,減少DOM的操作,不一定非要用到虛擬DOM,而可以直接對DOM進行操作.
  • 這就得先理解DOM樹.
  • 先看一個瀏覽器得請求過程:
    1.用戶輸入網(wǎng)址后,瀏覽器像服務(wù)器發(fā)送HTTP請求獲得HTML頁面
    2.得到頁面后,HTML解釋器、詞法分析器、語法分析器就會把HTML從字節(jié)流解釋成DOM樹的結(jié)構(gòu)(過程比較復(fù)雜,也許會開一篇新文章具體說明)
    3.得到DOM樹后,WebKit會分批次的將結(jié)果詞語返回給渲染線程進行渲染
  • 上面對DOM的產(chǎn)生和渲染說的比較細了,這樣說的主要原因是: 說明沒有一個類或者方法,可以得到內(nèi)存中待渲染的DOM樹(有可能要,但是我不知道QAQ).
  • 下面開始逐步實現(xiàn)虛擬DOM

createElement

  • 我們想實現(xiàn)以下結(jié)構(gòu)
  • 語法如下:
let vertualDom = createElement('ul', { class: 'list'}, [createElement('ul', { class: 'list'}, ['a']),createElement('ul', { class: 'list'}, ['b']),createElement('ul', { class: 'list'}, ['c']) ])
  • 我們想通過createElement之后,變?yōu)閷ο?結(jié)構(gòu)如下:
  • 很顯然,可以在創(chuàng)建虛擬節(jié)點時,返回一個VNode類,其中包含3個屬性(type、props、children)
class VNode {constructor(type, props, children) {this.type = type;this.props = props;this.children = children;} }const createElement = (type, props, children) {return new VNode(type, props, children); }
  • 上面之后,就可以返回一個虛擬DOM對象了.
  • 下面需要一個render方法,根據(jù) 虛擬DOM對象 來生成真實的DOM,并渲染.

render

  • render方法接收一個虛擬dom對象,根據(jù)對象創(chuàng)建真實的DOM
  • 1.首先我們根據(jù)傳入的對象,創(chuàng)建ul
const render = (vnode) {let el = document.createElement(vnode.type);return el; }
  • 打印一下:
let vertualDom = createElement('ul', { class: 'list' }, [createElement('ul', { class: 'list' }, ['a']),createElement('ul', { class: 'list' }, ['b']),createElement('ul', { class: 'list' }, ['c']), ])let el = render(vertualDom);console.log(el);

  • 2.有了DOM之后,我們給dom設(shè)置屬性.由于屬性可能比較多,
  • 因此我們使用for ... in 拿到鍵和值
  • 使用setAttribute來設(shè)置屬性
const render = (vnode) => {let el = document.createElement(vnode.type);let props = vnode.type;for(let key in props) {el.setAttribute(key, props[key]);} }

  • 檢測一下,改寫vertualDom
let vertualDom = createElement('ul', { class: 'list', style:'border:1px solid black' }, [createElement('ul', { class: 'list' }, ['a']),createElement('ul', { class: 'list' }, ['b']),createElement('ul', { class: 'list' }, ['c']), ]) let el = render(vertualDom); document.body.appendChild(el);

  • 現(xiàn)在有了節(jié)點和節(jié)點上面的屬性,下面需要渲染其子元素…
  • 很自然的想到了遞歸.
  • 遍歷其子元素,如果是VNode類型,就在調(diào)用render,否則認為其是一個文本節(jié)點.使用document.createTextNode創(chuàng)之
const render = (vnode) => {let el = document.createElement(vnode.type);let props = vnode.props;for (let key in props) {el.setAttribute(key, props[key]);}vnode.children.forEach(child => {child = child instanceof VNode ? render(child) : document.createTextNode(child);el.appendChild(child);})return el; }

總結(jié)

以上是生活随笔為你收集整理的javascript --- [虚拟DOM] 初始化 实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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