xxdom.js is a lightweight JavaScript library that provides incremental
DOM rendering through declarative directives. It allows developers to
bind JavaScript data to HTML elements using attribute-based directives
(like xx-for, xx-if, xx-text) and mustache-style interpolation
({{expression}}).
The library implements a manual reactivity model where developers
explicitly call xx() to trigger DOM updates after data changes,
providing precise control over rendering cycles.
You can play with the code online on jsfiddle.net.
Load xx.min.js and you are ready for rendering dynamic content with well known {{expression}} syntax.
The expression in-between {{}} is pure JavaScript.
<script src="https://4k2.de/xxdomjs/dist/xx.min.js"></script>
Hello {{ world + '!' }} <br>
Today is: {{ (new Date).toDateString() }}.
<script>
var world="world";
</script>You can bind an "xx-scope" to an HTML element. Additionally to the global JavaScript scope, every expression placed in one of the children have also access to this xx-scope. This works very much like local variables in js functions.
<div xx-scope="{ x:'local X'}">
Access local var x = {{x}}<br>
Access global var world = {{world}}
</div>Within event handlers the xx-scope of that element can be accessed by
the new property $scope. As a side effect, reading the property
$scope also schedules a render update.
You can xx-text the result of an expression to the elements el.innerText.
Hello <span xx-text="world"></span><span xx-text="'!'"></span>Loop over an iterable collection of something and access the items in there on "xx-scope".
<ul>
<li xx-for="item of things.reverse()">
The {{item.name}} is
<span xx-style="{color: (item.color)}" xx-text="item.color"></span>.
</li>
</ul>
<script>
var things = [
{ name: 'banana', color: 'blue' },
{ name: 'fox', color: 'brown'},
{ name: 'ball', color: 'red' },
];
</script>Yes, we have also an if:
<div xx-scope="{ isCool: true }">
Criss-Cross <span xx-if="isCool">is cool!</span>
</div>xx-style uses the key-value pairs of a js object as "style property" and "value". xx-class use the keys as the "classname" and its value is an boolean expression for using or not using this "classname".
<div xx-scope="{ isSelected: true, acolor: 'blue' }">
<div xx-style="{width: '300px', color: acolor}" xx-class="{ selected: isSelected }">
Criss-Cross
</div>
</div>xx-prop bind to element properties. xx-prop expects an js-object. The
key names of this js-object are the element property names to assign to.
<input xx-prop="{value: aValue}">will do on every value change:
elInput.value = aValue;xx-attr bind to element attributes. xx-attr expects an js-object. The
key names of this js-object are the element attribute names to assign to.
<input xx-attr="{hint: aHint}">will do on every value change:
elInput.setAttribute('hint', aHint);Define a new component with <template xx-component="{name}"> and use it with its name <{name}></{name}>:
<abc></abc>
<abc></abc>
<template xx-component="abc">
<div>The quick brown fox jumps over the lazy dog.</div>
</template>The HTML document will be rendered with Criss-Cross after the "DOMContentLoaded" event.
If the data/your model changes, you can re-render the DOM by calling xx.render() or
short just xx(). Only changed values will trigger a change on the HTML element. On
xx-for loops, the item identity operator ('===') is used to detect additions, deletions,
replacements and kept items. If only the item content changes, its HTML element only gets
an update.
<div> It is: {{ new Date }}</div>
<script>setInterval(xx, 1000);</script>Use git:
git clone https://github.com/jensh/xxdomjs.git xxdomOr npm:
npm install xxdomHere is a link to all above examples in action. The other examples from this repo.
Have fun!
We are interested in your thoughts!
Twitter: @jens4321