Skip to content

Instantly share code, notes, and snippets.

@bravelincy
Last active May 8, 2017 14:13
Show Gist options
  • Save bravelincy/20d26beb5ea5a54af518c0ce0f9b627a to your computer and use it in GitHub Desktop.
Save bravelincy/20d26beb5ea5a54af518c0ce0f9b627a to your computer and use it in GitHub Desktop.
/** @jsx tag */
function tag(type, props, ...children) {
return {type, props, children};
}
function createElement(node) {
if (typeof node === 'string') {
return document.createTextNode(node);
} else {
let $root = document.createElement(node.type);
node.children
.map(createElement)
.forEach($el => $root.appendChild($el))
return $root;
}
}
function updateElement($root, newNode, oldNode, index = 0) {
if (!oldNode) {
$root.appendChild(createElement(newNode));
} else if (!newNode) {
$root.removeChild($root.childNodes[index]);
} else if (changed(newNode, oldNode)) {
$root.replaceChild(
createElement(newNode),
$root.childNodes[index]
)
} else if (newNode.type) {
const len = Math.max(newNode.children.length, oldNode.children.length);
for (let i = 0; i < len; i++) {
updateElement(
$root.childNodes[index],
newNode.children[i],
oldNode.children[i],
i
)
}
}
}
function changed(node1, node2) {
const t1 = typeof node1, t2 = typeof node2;
return t1 !== t2 ||
t1 === 'string' && node1 !== node2 ||
node1.type !== node2.type
}
let treeA = (
<div class="box">
<ul class="list">
<li>item 1</li>
<li>item 2</li>
</ul>
<input type="text"/>
</div>
)
let treeB = (
<div class="box">
<ul class="list">
<li>hello!</li>
</ul>
<input type="text"/>
</div>
)
const $root = document.getElementById('root');
const $btn = document.getElementById('btn');
btn.addEventListener('click', e => {
let temp = treeA;
treeA = treeB;
treeB = temp;
updateElement($root, treeA, treeB)
});
updateElement($root, treeA)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment