项目作者: reactivelib

项目描述 :
Virtual reactive DOM using simple JSON objects without additional compilation steps.
高级语言: TypeScript
项目地址: git://github.com/reactivelib/html.git
创建时间: 2018-04-03T14:31:58Z
项目社区:https://github.com/reactivelib/html

开源协议:MIT License

下载


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:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@reactivelib/html@latest/dist/reactivelib.min.js"></script>
  5. </head>
  6. <body>
  7. <div id="myForm"></div>
  8. <script type="text/javascript">
  9. var reactive = reactivelib.reactive;
  10. var html = reactivelib.html;
  11. function createInput(){
  12. //we create a reactive property object for the input.
  13. var props = reactive({
  14. value: 0
  15. });
  16. return {
  17. //We define a new html element with "input" tag name
  18. tag: "input",
  19. //Define what properties the html element has
  20. prop: props,
  21. //Define what attributes the html element has
  22. attr: {
  23. type: "number"
  24. },
  25. //Define event handlers for the html element
  26. event: {
  27. //We listen to the keyup and mouseup event of the input element and update the reactive property object value
  28. keyup: (event) => {
  29. props.value = event.target.value;
  30. },
  31. mouseup: (event) => {
  32. props.value = event.target.value;
  33. }
  34. }
  35. }
  36. }
  37. var input1 = createInput();
  38. var input2 = createInput();
  39. // Create div that prints the sum of the 2 inputs.
  40. var result = {
  41. // html element with "div" tag name
  42. tag: "div",
  43. //This getter will be called again if the reactive value of input1 or input2 changes,
  44. //causing a rerendering of this html elements children
  45. get child(){
  46. return "Sum is: "+(parseInt(input1.prop.value) + parseInt(input2.prop.value))
  47. }
  48. }
  49. var form = {
  50. tag: "div",
  51. //The child elements of this html element
  52. child: [{tag: "div", child: input1}, {tag: "div", child: input2}, result]
  53. }
  54. // attach the form to the "myForm" div
  55. html.attach(document.getElementById("myForm"), form);
  56. </script>
  57. </body>
  58. </html>

When the user changes the input, the result will automatically be updated.

Installation

  1. npm install @reactivelib/reactive

commonjs

  1. var html = require("@reactivelib/html");
  2. html.attach(document.getElementById("myElement"),{
  3. tag: "div",
  4. child: "Hello"
  5. })

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.

  1. <head>
  2. <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@reactivelib/html@latest/dist/reactivelib.min.js"></script>
  3. </head>
  4. <body>
  5. <script type="text/javascript">
  6. //reactive package
  7. var reactive = reactivelib.reactive;
  8. //this package
  9. var html = reactivelib.html;
  10. </script>
  11. </body>

Typescript

  1. import * as html from '@reactivelib/html';
  2. html.attach(document.getElementById("myElement"),{
  3. tag: "div",
  4. child: "Hello"
  5. })

Typescript with “esModuleInterop”

When using “esModuleInterop” option, you can also import as follows:

  1. import html from '@reactivelib/html';
  2. html.attach(document.getElementById("myElement"),{
  3. tag: "div",
  4. child: "Hello"
  5. })

or

  1. import {attach} from '@reactivelib/html';
  2. attach(document.getElementById("myElement"),{
  3. tag: "div",
  4. child: "Hello"
  5. })

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:

  1. var el = {
  2. tag: "div",
  3. child: "Hello",
  4. attr: {
  5. id: "panel"
  6. },
  7. style: {
  8. background: "black"
  9. }
  10. }

would render following html element:

  1. <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

  1. <div id="element"></div>
  1. var el = {
  2. tag: "div",
  3. child: ["Input number: ",{
  4. tag: "input",
  5. attr :{
  6. type: "number"
  7. },
  8. prop: {
  9. value: 5
  10. }
  11. }]
  12. }
  13. 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:

  1. <div id="element">
  2. Input number: <input type="number" />
  3. </div>

Note that defining

  1. 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:

  1. var el = reactivelib.reactive({
  2. tag: "div",
  3. child: "Hello"
  4. })

This renders following html element

  1. <div>Hello</div>

We can now change the content of the div element like follows:

  1. el.child = "New content"

The content of the html element will be automatically refreshed:

  1. <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:

  1. var el = {
  2. tag: "div",
  3. child: "Hello",
  4. onAttached: function(){
  5. console.log("on attached called")
  6. }
  7. };
  8. reactivelib.html.attach(document.getElementById("element"), el);
  9. //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:

  1. var el = {
  2. tag: "div",
  3. child: "Hello",
  4. onAttached: function(){
  5. console.log("on attached called")
  6. },
  7. onDetached: function(){
  8. console.log("on detached called")
  9. }
  10. };
  11. reactivelib.html.attach(document.getElementById("element"), el);
  12. //at some later point, console will print "on attached called"
  13. //Some time later
  14. reactivelib.html.detach(el);
  15. //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:

  1. var el = {
  2. tag: "div",
  3. child: {
  4. tag: "div",
  5. child: "Hello",
  6. onAttached: function(){
  7. var node = el.node;
  8. console.log("html element: "+node.element)
  9. console.log("parent virtual dom object: "+node.parentModel);
  10. },
  11. onDetached: function(){
  12. }
  13. }
  14. };

Projects using this module

ReactiveChart