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

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

生活随笔

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

javascript

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

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

說(shuō)明

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

為什么提出 -> DOM操作慢

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

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

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

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

為什么提出 -> DOM樹(shù)的概念

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

createElement

  • 我們想實(shí)現(xiàn)以下結(jié)構(gòu)
  • 語(yǔ)法如下:
let vertualDom = createElement('ul', { class: 'list'}, [createElement('ul', { class: 'list'}, ['a']),createElement('ul', { class: 'list'}, ['b']),createElement('ul', { class: 'list'}, ['c']) ])
  • 我們想通過(guò)createElement之后,變?yōu)閷?duì)象,結(jié)構(gòu)如下:
  • 很顯然,可以在創(chuàng)建虛擬節(jié)點(diǎn)時(shí),返回一個(gè)VNode類(lèi),其中包含3個(gè)屬性(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); }
  • 上面之后,就可以返回一個(gè)虛擬DOM對(duì)象了.
  • 下面需要一個(gè)render方法,根據(jù) 虛擬DOM對(duì)象 來(lái)生成真實(shí)的DOM,并渲染.

render

  • render方法接收一個(gè)虛擬dom對(duì)象,根據(jù)對(duì)象創(chuàng)建真實(shí)的DOM
  • 1.首先我們根據(jù)傳入的對(duì)象,創(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來(lái)設(shè)置屬性
const render = (vnode) => {let el = document.createElement(vnode.type);let props = vnode.type;for(let key in props) {el.setAttribute(key, props[key]);} }

  • 檢測(cè)一下,改寫(xiě)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é)點(diǎn)和節(jié)點(diǎn)上面的屬性,下面需要渲染其子元素…
  • 很自然的想到了遞歸.
  • 遍歷其子元素,如果是VNode類(lèi)型,就在調(diào)用render,否則認(rèn)為其是一個(gè)文本節(jié)點(diǎn).使用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] 初始化 实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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