虚拟dom的实现,主要是通过控制数据来操作dom,Vue,React等框架都有用到,看代码
目标dom
<ol id='ol-list'>
<li class='item'>Item 1</li>
<li class='item'>Item 2</li>
<li class='item'>Item 3</li>
</ol>
js要想实现目标dom,只需要记录标签名,标签属性,子元素和元素内容数据就行了
export default Ele = (tagName, props, children) => {
this.tagName = tagName
this.props = props
this.children = children
}
import * as el from 'Ele';
var ol = el('ol', {id: 'ol-list'}, [
el('li', {class: 'item'}, ['Item 1']),
el('li', {class: 'item'}, ['Item 2']),
el('li', {class: 'item'}, ['Item 3'])
]);
ol其实就是个js对象表示的dom元素,通过下边的方法,将它转化为真正的dom
Ele.prototype.render = function () {
var e = document.createElement(this.tagName); // 创建元素
var props = this.props;
for (var propName in props) { // 设置 DOM 属性
var propValue = props[propName];
e.setAttribute(propName, propValue);
}
var children = this.children || [];
children.forEach(function (child) {
var childE = (child instanceof Element)
? child.render() // 子节点也是虚拟 DOM,递归构建
: document.createTextNode(child); // 字符串,构建文本节点
e.appendChild(childE);
});
return e;
}
最后就是直接调用方法生成dom元素,添加到页面中了
var olE = Ele.render()
document.body.appendChild(olE);
当可以使用js来表示dom元素的时候,每次刷新就不用全局刷新了,对比dom不同,更新变化的dom就可以了,
比较两个 DOM 树的差异是 Virtual DOM 算法最核心的部分,这也是所谓的 Virtual DOM 的diff 算法。