Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/DylanPiercey/set-dom
📑 Lightweight dom diffing with plain old html.
https://github.com/DylanPiercey/set-dom
Last synced: 18 days ago
JSON representation
📑 Lightweight dom diffing with plain old html.
- Host: GitHub
- URL: https://github.com/DylanPiercey/set-dom
- Owner: DylanPiercey
- License: mit
- Created: 2016-05-25T03:00:40.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2018-08-20T21:36:48.000Z (about 6 years ago)
- Last Synced: 2024-05-08T20:54:59.386Z (6 months ago)
- Language: JavaScript
- Homepage:
- Size: 365 KB
- Stars: 183
- Watchers: 9
- Forks: 20
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
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](https://github.com/tbranyen/diffhtml), [morphdom](https://github.com/patrick-steele-idem/morphdom) and my knowledge from [tusk](https://github.com/DylanPiercey/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
```console
npm install set-dom
```#### [Download](https://raw.githubusercontent.com/DylanPiercey/set-dom/master/dist/set-dom.js)
```htmldefine(['set-dom'], function (setDOM) {...}); // AMD
window.setDOM; // Global set-dom if no module system in place.```
# Example
```javascript
const setDOM = require("set-dom");// We will use handlebars for our example.
const hbs = require("handlebars");
const homePage = hbs.compile(`
My App
{{title}}
{{#each frameworks}}
{{name}} is pretty cool.
{{/each}}
`);// 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](https://github.com/bevacqua/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](https://davidwalsh.name/event-delegate). Check out something like [component-delegate](https://github.com/component/delegate) for a lightweight library that does this for you. Or if you are using [Rill](https://github.com/rill-js/rill) checkout [@rill/delegate](https://github.com/rill-js/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.```js
// 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](https://vdom-benchmark.github.io/vdom-benchmark/) website.### Contributions
* Use `npm test` to run tests.
Please feel free to create a PR!