sampleReactFram
react的功能的简单实现
by ZhiLin GeGe
HTML
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<button id="reload">替换DOM</button>
<div id="root"></div>
JavaScript
/** @jsx h */
function h(type, props, ...children){ // 基于jsx的语法,创建元素,类似于React.createElement()的第一步;
return {type, props, children};
}
console.log(1);
function createElement(node) {
if(typeof node === "string") { //当节点为字符串时
return document.createTextNode(node.children);
}
/*const $el = document.createElement(node.type);
node.children
.map(child => createElement(child))
.forEach(childNode => $el.appendChild(childNode));
return $el; */
const $el = document.createElement(node.type);
console.log("$el",$el);
node.children.map(createElement)
.forEach($el.appendChild.bind($el));
return $el;
}
const list = (
<ul class="list">
<li>苹果</li>
<li>西瓜</li>
</ul>
);
createElement(list);
console.log(createElement(list));
/* function h(type,props,...children){
return {type,props,children};
}
function createElement(node){
//如果只是一个字符串
if(typeof node === 'string'){
return document.createTextNode(node);
}
//如果是 HTML 的节点的形式
const $el = document.createElement(node.type);
node.children.map((child) => createElement(child) )
.forEach((newNode) => $el.appendChild(newNode));
return $el;
}
//diff 算法
function changed(nodeNew,nodeOld){
return typeof nodeOld !== typeof nodeNew ||
typeof nodeNew === 'string' && nodeOld !== nodeNew ||
nodeOld.type !== nodeNew.type
}
//更新算法
function updateElement($parent, newNode, oldNode, index = 0) {
if (!oldNode) { //原本的节点没有,那么就插入新的节点
$parent.appendChild(
createElement(newNode)
);
} else if (!newNode) { //新的节点没有内容,旧的节点就应该移除
$parent.removeChild(
$parent.childNodes[index]
);
} else if (changed(newNode, oldNode)) { //比较新旧两个节点是否有变更
$parent.replaceChild(
createElement(newNode), //新节点
$parent.childNodes[index] //之前的旧节点
);
} else if (newNode.type) { //递归处理自身的子节点
const newLength = newNode.children.length;
const oldLength = oldNode.children.length;
for (let i = 0; i < newLength || i...