@reactivelib/html v1.0.0
This is a virtual dom using only plain json objects and the reactive package. There are no additional compilation steps. For example, let's create a simple form to add 2 numbers:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@reactivelib/html@latest/dist/reactivelib.min.js"></script>
</head>
<body>
<div id="myForm"></div>
<script type="text/javascript">
var reactive = reactivelib.reactive;
var html = reactivelib.html;
function createInput(){
//we create a reactive property object for the input.
var props = reactive({
value: 0
});
return {
//We define a new html element with "input" tag name
tag: "input",
//Define what properties the html element has
prop: props,
//Define what attributes the html element has
attr: {
type: "number"
},
//Define event handlers for the html element
event: {
//We listen to the keyup and mouseup event of the input element and update the reactive property object value
keyup: (event) => {
props.value = event.target.value;
},
mouseup: (event) => {
props.value = event.target.value;
}
}
}
}
var input1 = createInput();
var input2 = createInput();
// Create div that prints the sum of the 2 inputs.
var result = {
// html element with "div" tag name
tag: "div",
//This getter will be called again if the reactive value of input1 or input2 changes,
//causing a rerendering of this html elements children
get child(){
return "Sum is: "+(parseInt(input1.prop.value) + parseInt(input2.prop.value))
}
}
var form = {
tag: "div",
//The child elements of this html element
child: [{tag: "div", child: input1}, {tag: "div", child: input2}, result]
}
// attach the form to the "myForm" div
html.attach(document.getElementById("myForm"), form);
</script>
</body>
</html>
When the user changes the input, the result will automatically be updated.
Installation
npm install @reactivelib/reactive
commonjs
var html = require("@reactivelib/html");
html.attach(document.getElementById("myElement"),{
tag: "div",
child: "Hello"
})
Browser
We provide a browser ready file "dist/reactivelib.min.js" in the npm package that exposes the global "reactivelib" and includes both this and the reactive package.
<head>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@reactivelib/html@latest/dist/reactivelib.min.js"></script>
</head>
<body>
<script type="text/javascript">
//reactive package
var reactive = reactivelib.reactive;
//this package
var html = reactivelib.html;
</script>
</body>
Typescript
import * as html from '@reactivelib/html';
html.attach(document.getElementById("myElement"),{
tag: "div",
child: "Hello"
})
Typescript with "esModuleInterop"
When using "esModuleInterop" option, you can also import as follows:
import html from '@reactivelib/html';
html.attach(document.getElementById("myElement"),{
tag: "div",
child: "Hello"
})
or
import {attach} from '@reactivelib/html';
attach(document.getElementById("myElement"),{
tag: "div",
child: "Hello"
})
Creating html elements
Html elements can be created with a json object that contains following properties:
property | description |
---|---|
tag | defines the html tag name of the html element to create |
prop | defines the properties of the html element. This sets the properties of the javascript object that you get when using document.getElementById |
attr | defines the attributes of the html element |
style | defines the style attribute of the html element |
event | defines the event handlers of the html element |
child | defines the children of the html element. Can be a string, a virtual dom element or an array containing string or virtual dom elements |
For example, following json object:
var el = {
tag: "div",
child: "Hello",
attr: {
id: "panel"
},
style: {
background: "black"
}
}
would render following html element:
<div id="panel" style="background: black">Hello</div>
Attaching to the DOM
In order to render the virtual dom elements, you need to attach them to the dom. You can accomplish that with the "attach" method as follows:
Assume we have following html element somewhere in the page
<div id="element"></div>
var el = {
tag: "div",
child: ["Input number: ",{
tag: "input",
attr :{
type: "number"
},
prop: {
value: 5
}
}]
}
reactivelib.html.attach(document.getElementById("element"), "el")
The attach renders and appends the rendered html element to the element given to the attach method. This is how the html element looks like after attaching:
<div id="element">
Input number: <input type="number" />
</div>
Note that defining
prop: {value: 5}
we also set the value of the input element to 5.
Reactive properties
You can use the reactive package to create virtual dom elements that are reactive. Any property you create and make reactive will be automatically kept in sync with the rendered html element. For example:
var el = reactivelib.reactive({
tag: "div",
child: "Hello"
})
This renders following html element
<div>Hello</div>
We can now change the content of the div element like follows:
el.child = "New content"
The content of the html element will be automatically refreshed:
<div>New content</div>
For a more complex example, take a look at the example at the top of this readme file.
Lifecycle
When you attach a virtual dom element to the dom, the "onAttached" method will be called if available:
var el = {
tag: "div",
child: "Hello",
onAttached: function(){
console.log("on attached called")
}
};
reactivelib.html.attach(document.getElementById("element"), el);
//at some later point, console will print "on attached called"
There is also a "onDetached" method when you remove the virtual dom element from the dom:
var el = {
tag: "div",
child: "Hello",
onAttached: function(){
console.log("on attached called")
},
onDetached: function(){
console.log("on detached called")
}
};
reactivelib.html.attach(document.getElementById("element"), el);
//at some later point, console will print "on attached called"
//Some time later
reactivelib.html.detach(el);
//at some later point, console will print "on detached called"
Note that rendering happens asynchronously inside an animation frame. Therefore, the lifecycle methods are called at some point in the future after attaching or detaching.
The node object
The node object gives you access to the html element and parent and is available after the virtual dom element has been attached:
var el = {
tag: "div",
child: {
tag: "div",
child: "Hello",
onAttached: function(){
var node = el.node;
console.log("html element: "+node.element)
console.log("parent virtual dom object: "+node.parentModel);
},
onDetached: function(){
}
}
};
Projects using this module
6 years ago