當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
javascript --- 将DOM结构转换成虚拟DOM 虚拟DOM转换成真实的DOM结构
生活随笔
收集整理的這篇文章主要介紹了
javascript --- 将DOM结构转换成虚拟DOM 虚拟DOM转换成真实的DOM结构
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
虛擬DOM的實現
使用虛擬DOM的原因: 減少回流與重繪
將DOM結構轉換成對象保存到內存中
<img /> => { tag: 'img'}
文本節點 => { tag: undefined, value: '文本節點' }
<img title="1" class="c" /> => { tag: 'img', data: { title = "1", class="c" } }
<div><img /></div> => { tag: 'div', children: [{ tag: 'div' }]}
根據上面可以寫出虛擬DOM的數據結構
class VNode {constructor(tag, data, value, type) {this.tag = tag && tag.toLowerCase()this.data = datathis.value = valuethis.type = typethis.children = []}appendChild(vnode){this.children.push(vnode)} }可能用到的基礎知識
- 判斷元素的節點類型: node.nodeType
- 獲取元素類型的標簽名和屬性 && 屬性中具體的鍵值對,保存在一個對象中
- 獲取當前節點的子節點
算法思路
- 使用document.querySelector獲取要轉換成虛擬DOM的模板
- 使用nodeType方法來獲取是元素類型還是文本類型
- 若是元素類型
- 使用nodeName獲取標簽名
- 使用attributes獲取屬性名,并將具體的屬性保存到一個對象_attrObj中
- 創建虛擬DOM節點
- 考慮元素類型是否有子節點,使用遞歸,將子節點的虛擬DOM存入其中
- 若是文本類型
- 直接創建虛擬DOM,不需要考慮子節點的問題
以上寫了虛擬DOM的數據結構,以及使用getVNode方法將真實DOM結構轉換成虛擬DOM,下面開始逐步實現getVNode方法
- 判斷節點類型,并返回虛擬DOM
- 下面根據元素類型和文本類型分別創建虛擬DOM
總體代碼
class VNode {constructor(tag, data, value, type) {this.tag = tag && tag.toLowerCase()this.data = datathis.value = valuethis.type = typethis.children = []}appendChild(vnode){this.children.push(vnode)} }function getVNode(node) {let nodeType = node.nodeTypelet _vnode = nullif (nodeType == 1) {let tag = node.nodeNamelet attrs = node.attributeslet _data = {}for (let i = 0, len = attrs.length; i < len; i++) {_data[attrs[i].nodeName] = attrs[i].nodeValue}_vnode = new VNode(tag, _data, undefined, nodeType)let childNodes = node.childNodesfor (let i = 0, len = childNodes.length; i < len; i++) {_vnode.appendChild(getVNode(childNodes[i]))}} else if (nodeType == 3) {_vnode = new VNode(undefined, undefined, node.nodeValue, nodeType)}return _vnode }let root = document.querySelector('#root') let vroot = getVNode(root) console.log(vroot)將虛擬DOM轉換成真實的DOM結構
此過程就是上面的反過程
可能用到的知識點
- 創建文本節點
- 創建元素節點
- 給元素節點添加屬性
- 給元素節點添加子節點
算法思路
- 虛擬DOM的結構中,元素的節點類型存儲在type中,根據type可以判斷出是文本節點還是元素節點
- 若為文本節點,直接返回一個文本節點return document.createTextNode(value)
- 若為元素節點
- 創建一個node節點:_node = document.createElement(tag)
- 遍歷虛擬DOM中的data屬性,將其中的值賦給node節點
- 給當前節點添加子節點
具體實現
function parseVNode(vnode){let type = vnode.typelet _node = nullif(type == 3){return document.createTextNode(vnode.value)} else if (type == 1){_node = document.createElement(vnode.tag)let data = vnode.datalet attrName,attrValueObject.keys(data).forEach(key=>{attrName = keyattrValue = data[key]_node.setAttribute(attrName, attrValue)})// 考慮子元素let children = vnode.childrenchildren.forEach( subvnode =>{_node.appendChild(parseVNode(subvnode))})}return _node }驗證:
let root = querySelector('#root') let vroot = getVNode(root) console.log(vroot) let root1 = parseVNode(vroot) console.log(root1)總結
以上是生活随笔為你收集整理的javascript --- 将DOM结构转换成虚拟DOM 虚拟DOM转换成真实的DOM结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fluidsim元件库下载_FluidS
- 下一篇: javascript --- vue中