Detalhes do pacote

set-dom

DylanPiercey3.8kMIT7.5.2

Lightweight dom diffing library with plain old html.

diff, dom, hyperx, jsx

readme (leia-me)

Set-DOM Logo
API stability Standard NPM version Build status Test Coverage File size Downloads Gitter Chat Browser Matrix

A lightweight library to update DOM and persist state. IE: React diffing with html instead of JSX (bring your own templating language).

Why

JSX is great but there are so many other nice alternatives. React is great but it's clunky and opinionated.

This is inspired by diffhtml, morphdom and my knowledge from tusk. I set out to create a no nonsense "dom to dom" diffing algorithm that was fast and compact.

Features

  • ~800 bytes min/gzip.
  • Minimal API.
  • Keyed html elements (data-key or id to shuffle around nodes).
  • Use whatever you want to generate html.

Installation

Npm

npm install set-dom

Download

<script type="text/javascript" src="set-dom.js"></script>
<script>
    define(['set-dom'], function (setDOM) {...}); // AMD
    window.setDOM; // Global set-dom if no module system in place.
</script>

Example

const setDOM = require("set-dom");

// We will use handlebars for our example.
const hbs = require("handlebars");
const homePage = hbs.compile(`
    <html>
        <head>
            <title>My App</title>
            <meta name="description" content="Rill Application">
        </head>
        <body>
            <div class="app" data-key="home-page">
                {{title}}
                {{#each frameworks}}
                    <div data-key={{name}}>
                        {{name}} is pretty cool.
                    </div>
                {{/each}}
            </div>
            <script src="/app.js"/>
        </body>
    </html>
`);

// You can replace the entire page with your new html (only updates changed elements).
setDOM(document, homePage({
    title: "Hello World.",
    frameworks: [
        { name: "React" },
        { name: "Angular" },
        { name: "Ember" },
        { name: "Backbone" },
        { name: "Everything" }
    ]
}));

// Or update individual elements.
setDOM(myElement, myHTML);

API

  • setDOM(HTMLEntity, html|HTMLEntity) : Updates existing DOM to new DOM in as few operations as possible.

Advanced Tips

Keys

Just like React (although slightly different) set-dom supports keyed nodes. To help the diffing algorithm reposition your elements be sure to provide a data-key or id attribute on nodes inside a map. This is optional but key for performance when re-ordering/modifying lists.

Another key difference from React is that set-dom simply can't tell when you are rendering an entirely different component. As such it is good practice to use data-key when you know that most of the html will be discarded (like when rendering an entirely different page) to skip the diffing process entirely.

Checksum

Another trick to help set-dom with it's diffing algorithm is to provide a data-checksum attribute. This attribute will only do any diff on an element (and it's children) if the checksum changes allowing you to skip diffing entire trees of the document. Check out hash-sum for a quick and simple checksum that you can use in your templates. Simply hash the state/data for your view and set-dom will only do any changes to the document once the hash has changed.

Ignored

Sometimes it is required to simply escape the whole diffing paradigm and do all of the manual dom work yourself. With set-dom it is easy to include these types of elements in the page using a special data-ignore attribute.

Any elements that have a data-ignore will only be diffed when the data-ignore attribute is removed. The only thing set-dom will do for you in this case is automatically add and remove the element.

Event delegation

Unlike React, set-dom does not provide a way for you to add event listeners to your elements. Fortunately there is a simple approach that enables this that you have probably used before (aka jquery), event delegation. Check out something like component-delegate for a lightweight library that does this for you. Or if you are using Rill checkout @rill/delegate.

Mounting and Dismounting.

Often you need the ability to intercept when a component is inserted or removed from the DOM. Keyed elements (those with data-key or id attributes) will automatically emit custom mount and dismount events when they are inserted and removed from the DOM.

You can use these events to handle setup and teardown of complex components along side event delegation.

Overrides

You can also easily override the attributes used for both keying and ignoring by manually updating the KEY, CHECKSUM and IGNORE properties of set-dom like so.

// Change 'data-key' to 'data-my-key'
setDOM.KEY = 'data-my-key'

// Change 'data-checksum' to 'data-my-checksum'
setDOM.CHECKSUM = 'data-my-checksum'

// Change 'data-ignore' to 'data-my-ignore'
setDOM.IGNORE = 'data-my-ignore'

Benchmarks

Benchmarks are available on the vdom-benchmark website.

Contributions

  • Use npm test to run tests.

Please feel free to create a PR!

changelog (log de mudanças)

Change Log

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

7.5.0, 7.5.1, 7.5.2 - 2017-11-07

  • Add tests for html parser.
  • Fix parsing issue in Safari 9.

7.4.3 - 2017-08-09

  • Fix typo in readme.
  • Update dev dependencies.

7.4.3 - 2017-06-11

  • Update dev dependencies.

7.4.2 - 2017-04-18

  • Fix issue with dismount event not dispatching on keyed nodes.

7.4.1 - 2017-03-29

  • Cleanup code for mount an dismount events.

7.4.0 - 2017-03-29

  • Add isEqualNode checking (boosts perf up to 1.8x).

7.3.2, 7.3.3 - 2017-03-28

  • Optimize old (keyed) node removals.
  • Fix issue with keyed nodes sometimes being moved to the wrong spot.
  • Keyed nodes will no longer be moved when they are already in the proper position.

7.3.0, 7.3.1 - 2017-03-26

  • Fix issue in ie9 with parsing automatically inserted html like <tbody>.

7.2.0 - 2017-03-26

  • Add support for diffing against a DocumentFragment (diffs childNodes).

7.1.0 - 2017-03-26

  • Improve html string parsing performance in older browsers.
  • Remove trying to parse html string as XML (caused issues with special elements like tables).

7.0.3 - 2017-03-20

  • Fixed license date and name.
  • Add lcov report when testing locally.
  • Optimize one line.

7.0.2 - 2017-03-19

  • Refactored to use better variable names.

7.0.1 - 2017-03-15

  • Fixed regression in diffing algorithm with empty text nodes causing some nodes to be skipped.

7.0.0 - 2017-03-13

  • Switched to new diffing algorithm which is up to 50% faster and less memory intensive in some browsers.

6.0.1 - 2017-02-13

  • Fixed typo in README.
  • Added more tests for data-checksum.
  • Made DOMParser optional (IE < 8).

6.0.0 - 2016-12-19

  • Added data-checksum property. This aids in performance by allowing the user to provide a checksum which will be checked before diffing nodes. Allows users to skip the diffing algorithm by comparing state via checksum.

5.0.3, 5.0.4 - 2016-11-27

  • Updated devDependencies.

5.0.0, 5.0.1, 5.0.2 - 2016-10-19

  • Now uses DOMParser (and shim for older browsers) for faster html string parsing.
  • Minor compression optimization.
  • Change travis build to only be node 6 (Cross browser issues left to saucelabs).

4.0.3 - 2016-10-19

  • Fix issue when diffing namespaced attributes.

4.0.2 - 2016-10-10

  • Fix issue where data-key=SOME_INTEGER or id=SOME_INTEGER could conflict with the algorithm.

4.0.1 - 2016-10-06

  • Fix issue with mounting while switching node types.
  • Fix issue with initial mounting of nodes.

4.0.0 - 2016-10-06

  • Elements with data-key or id attributes will now emit custom mount and dismount events when added and removed from the DOM.

3.1.0 - 2016-09-24

  • Ignored elements will now be diffed when the next element is not ignored.

3.0.0 - 2016-09-20

  • Add minor diff optimization for replacing nodes.
  • Switch tests to mocha.
  • 100% test coverage.
  • Added source map to dist.
  • added build with travis
  • added code coverage with coveralls
  • switch to use makefile

2.0.5 - 2016-09-18

  • Updated dev devDependencies and add git tags.

2.0.0 - 2016-09-16

  • Added data-ignore attribute which will disable diffing for an element.
  • Added ability to override data-key and data-ignore attributes.
  • Added changelog.