把网站做成静态页面,个人网站建设教程pdf,信息图表设计网站,网页制作的公司企业说明
本篇主要说明为什么要使用虚拟DOM技术,以及如何实现简单的虚拟dom您将会学到: 1.原生JS对DOM的操作 2.虚拟DOM的相关概念 3.DIFF算法的基础概念 为什么提出 - DOM操作慢
我们使用createElement属性来创建一个最常见的div,看看一个最常见的DOM有多少个属性
scri…说明
本篇主要说明为什么要使用虚拟DOM技术,以及如何实现简单的虚拟dom您将会学到: 1.原生JS对DOM的操作 2.虚拟DOM的相关概念 3.DIFF算法的基础概念 为什么提出 - DOM操作慢
我们使用createElement属性来创建一个最常见的div,看看一个最常见的DOM有多少个属性
scriptconst div document.createElement(div);let str ;for(let key in div){str key ;}console.log(str);
/script可以看出,每个DOM其实是由很多内置的属性.因此,当DOM元素的操作过多的时候,其性能可想而知.这就迫使我们去想一个办法去减少DOM操作 为什么提出 - 对比Ajax技术的出现
早期的网页交互,是整个页面进行更新的.但是大多数时候,用户对页面的操作,只是一小部分,这就导致了大多数更新是多余的.于是产生了Ajax技术(网页的部分更新)可以模仿Ajax技术,去部分渲染DOM 为什么提出 - DOM树的概念
你可以会反驳,减少DOM的操作,不一定非要用到虚拟DOM,而可以直接对DOM进行操作.这就得先理解DOM树.先看一个浏览器得请求过程: 1.用户输入网址后,浏览器像服务器发送HTTP请求获得HTML页面 2.得到页面后,HTML解释器、词法分析器、语法分析器就会把HTML从字节流解释成DOM树的结构(过程比较复杂,也许会开一篇新文章具体说明) 3.得到DOM树后,WebKit会分批次的将结果词语返回给渲染线程进行渲染上面对DOM的产生和渲染说的比较细了,这样说的主要原因是: 说明没有一个类或者方法,可以得到内存中待渲染的DOM树(有可能要,但是我不知道QAQ).下面开始逐步实现虚拟DOM createElement
我们想实现以下结构 语法如下:
let vertualDom createElement(ul, { class: list}, [createElement(ul, { class: list}, [a]),createElement(ul, { class: list}, [b]),createElement(ul, { class: list}, [c])
])我们想通过createElement之后,变为对象,结构如下: 很显然,可以在创建虚拟节点时,返回一个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方法,根据 虚拟DOM对象 来生成真实的DOM,并渲染. render
render方法接收一个虚拟dom对象,根据对象创建真实的DOM1.首先我们根据传入的对象,创建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设置属性.由于属性可能比较多,因此我们使用for ... in 拿到键和值使用setAttribute来设置属性
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);现在有了节点和节点上面的属性,下面需要渲染其子元素…很自然的想到了递归.遍历其子元素,如果是VNode类型,就在调用render,否则认为其是一个文本节点.使用document.createTextNode创之
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;
}