@ciolabs/morphdom
v0.0.1
Published
A flexible wrapper around morphdom, a way to diff and patch DOM elements.
Readme
@ciolabs/morphdom
A flexible wrapper around morphdom, a way to diff and patch DOM elements.
Why?
morphdom is a great library for diffing and patching DOM elements. However, it lacks a few key pieces of flexibility to serve our needs.
It doesn't allow you to control which elements to consider when diffing. This is a problem since a single whitespace change in a large document can cause an outsided amount of work to be done.
There is no batteries-included way to ignore attributes when diffing. This is a problem since some attributes are not important to the application and can be ignored, especially when they are applied by our code (i.e. when connecting tinymce).
There is no way at all to control how attributes get updated. This means that even if you can ignore attributes when diffing, they will still be destroyed when the element is patched.
Install
npm install @ciolabs/morphdomUsage
morph
morph is a simplified version of morphdom that allows you to morph two elements together. Instead of providing all the options that morphdom does, morph provides a few key options that cover the majority of the use cases.
Some things it does:
- Ignores whitespace changes
- Ignores the given attributes
- Ignores the given classes
import { morph } from '@ciolabs/morphdom';
var el1 = document.createElement('div');
el1.dataset.foo = 'I wont change';
var el2 = document.createElement('div');
el2.dataset.foo = 'even if I change';
morph(el1, el2, {
ignoredAttributes: ['data-foo'],
});
expect(el1.dataset.foo).to.equal('I wont change');The morph function takes three arguments:
fromNode - The node to morph
toNode - The node that the fromNode should be morphed to or an HTML string
options - See below for supported options
Options:
ignoredAttributes- An array of attributes to ignore when diffing. If an attribute is ignored, it will not be updated when the element is patched.ignoredClasses- An array of classes to ignore when diffing. If a class is ignored, it will not be updated when the element is patched.
morphdom
You can use morphdom just like you would normally, but with a few extra options.
import { morphdom } from '@ciolabs/morphdom';
var el1 = document.createElement('div');
el1.className = 'foo';
var el2 = document.createElement('div');
el2.className = 'bar';
morphdom(el1, el2);
expect(el1.className).to.equal('bar');The morphdom function takes three arguments:
fromNode (Node)- The node to morph
toNode (Node|String) - The node that the fromNode should be morphed to (or an HTML string)
options - See below for supported options
Options:
getNodeKey(node)- Called to get theNode's unique identifier. This is used bymorphdomto rearrange elements rather than creating and destroying an element that already exists. This defaults to using theNode'sidproperty. (Note that form fields must not have anamecorresponding to forms' DOM properties, e.g.id.)filterNode(node)- Determines if the node should be used when diffing. If this function returnsfalsethen the node will not be used. Defaults to returningtrue.onBeforeNodeAdded(node)- Called before aNodein thetotree is added to thefromtree. If this function returnsfalsethen the node will not be added. Should return the node to be added.addChild(parentNode, node)- Called when adding a new child to a parent. By default,parentNode.appendChild(childNode)is invoked. Use this callback to customize how a new child is added.onNodeAdded(node)- Called after aNodein thetotree has been added to thefromtree.onBeforeElementUpdated(fromElement, toElement)- Called before aHTMLElementin thefromtree is updated. If this function returnsfalsethen the element will not be updated.updateElement(fromElement, toElement)- Called when updating an element. By default,morphdomwill update the element's attributes and children. Use this callback to customize how an element is updated.onElementUpdated(element)- Called after aHTMLElementin thefromtree has been updated.onBeforeNodeDiscarded(node)- Called before aNodein thefromtree is discarded. If this function returnsfalsethen the node will not be discarded.removeChild(parentNode, node)- Called when removing a child from a parent. By default,parentNode.removeChild(childNode)is invoked. Use this callback to customize how a child is removed.onNodeDiscarded(node)- Called after aNodein thefromtree has been discarded.onBeforeElementChildrenUpdated(fromElement, toElement)- Called before the children of aHTMLElementin thefromtree are updated. If this function returnsfalsethen the child nodes will not be updated.childrenOnly- Iftruethen only the children of thefromNodeandtoNodenodes will be morphed (the containing element will be skipped). Defaults tofalse.skipFromChildren(fromElement, toElement)- called when indexing a thefromElementtree. False by default. Returntrueto skip indexing the from tree, which will keep current items in place after patch rather than removing them when not found in thetoElement.
