Skip to content

Instantly share code, notes, and snippets.

@audinue
Created December 12, 2021 13:30
Show Gist options
  • Select an option

  • Save audinue/7f93ac67e11656f76cf379541bf4663e to your computer and use it in GitHub Desktop.

Select an option

Save audinue/7f93ac67e11656f76cf379541bf4663e to your computer and use it in GitHub Desktop.
Simple DOM diff :P
<script src="render.js"></script>
<script>
var a = 0
var b = 0
var c = function () {
return a + b
}
function render (e) {
if (e.type === 'input') {
if (e.target.id === 'a') {
a = e.target.valueAsNumber
a = isNaN(a) ? 0 : a
}
if (e.target.id === 'b') {
b = e.target.valueAsNumber
b = isNaN(b) ? 0 : b
}
}
return '<input id="a" type="number">'
+ ' + <input id="b" type="number">'
+ ' = <input value="' + c() + '" readonly>'
}
</script>
function render () {
return ''
}
addEventListener('DOMContentLoaded', function (e) {
var slice = [].slice
var timeout
function updateNode (previous, next) {
var i, len, attr, p, pl, n, nl
if (previous.nodeType !== next.nodeType
|| previous.nodeName !== next.nodeName) {
previous.parentNode.replaceChild(next, previous)
} else if (previous.nodeType === Node.TEXT_NODE) {
if (previous.textContent !== next.textContent) {
previous.textContent = next.textContent
}
} else if (previous.nodeType === Node.ELEMENT_NODE) {
for (i = next.attributes.length - 1; i > -1; i--) {
attr = next.attributes[i]
if (previous.getAttribute(attr.name) !== attr.value) {
previous.setAttribute(attr.name, attr.value)
}
}
for (i = previous.attributes.length - 1; i > -1; i--) {
attr = previous.attributes[i]
if (!next.hasAttribute(attr.name)) {
previous.removeAttribute(attr.name)
}
}
p = slice.call(previous.childNodes)
n = slice.call(next.childNodes)
pl = p.length
nl = n.length
if (pl < nl) {
for (i = pl; i < nl; i++) {
previous.appendChild(n[i])
}
} else if (pl > nl) {
for (i = nl; i < pl; i++) {
previous.removeChild(p[i])
}
}
len = Math.min(pl, nl)
for (i = 0; i < len; i++) {
updateNode(p[i], n[i])
}
}
}
function updateBody (event) {
clearTimeout(timeout)
timeout = setTimeout(function () {
var next = document.createElement('body')
next.innerHTML = render(event)
updateNode(document.body, next)
}, 1000 / 60)
}
addEventListener('keydown', updateBody)
addEventListener('keyup', updateBody)
addEventListener('input', updateBody)
addEventListener('submit', updateBody)
updateBody(e)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment