Skip to content

Instantly share code, notes, and snippets.

@barneycarroll
Last active November 8, 2019 06:28
Show Gist options
  • Save barneycarroll/43ad7df63e3a73ef7c39f0202e74eadd to your computer and use it in GitHub Desktop.
Save barneycarroll/43ad7df63e3a73ef7c39f0202e74eadd to your computer and use it in GitHub Desktop.
DOM patching without: provide two DOM elements, the second (and contents) will be modified such that it resembles the first
function patdj(target, update, preserve = true) {
if (update.nodeType != 1 && update.nodeType == target.nodeType)
target.nodeValue = update.nodeValue
else if (update.nodeType != target.nodeType || update.tagName !== target.tagName || update.type !== target.type){
const { nextSibling, parentNode } = target;
const replacement = preserve ? update.cloneNode(true) : update;
parentNode.removeChild(target);
if (nextSibling)
parentNode.insertBefore(replacement, nextSibling);
else
parentNode.appendChild(replacement);
}
else {
const properties = new Set();
for (const key in update)
properties.add(key);
for (const key in target)
properties.add(key);
for (const key of properties)
if (!(key in update))
delete target[key];
else if (update[key] !== target[key] && !isNaN(update[key]))
target[key] = update[key];
for (const key of new Set(
[...update.attributes, ...target.attributes].map(({ name }) => name)
))
if (!update.hasAttribute(key))
target.removeAttribute(key);
else {
const value = update.getAttribute(key);
if (value !== target.getAttribute(key))
target.setAttribute(key, value);
}
let index = Math.max(update.childNodes.length, target.childNodes.length);
while (index-- > 0){
if (!update.childNodes[index])
target.removeChild(target.childNodes[index]);
else
patdj(update.childNodes[index], target.childNodes[index]);
}
}
}
@barneycarroll
Copy link
Author

Revision 5 introduced sub-tree node patching at the expense of property patching

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment