Every javascript programmer from time to time has the need to insert a markup fragment on the page. For large fragments, template engines are used. And what if you need to insert small pieces many times? In plain js it is not easy and elegant to do this. The solution to the forehead is to use
innerHTML . But this is a terrible decision! I just turn up when I see it in code like this:
el.innerHTML = "<div id='main'>"+hello+"world!</div>";
Another solution proposed by Mozilla is the
html2dom library for generating html by building chained calls from a markup line. This solution is not bad enough, but it does not solve the main task - the need to simply and clearly describe the markup.
In the end, I decided to write my own library that solves all the necessary tasks - fast and secure DOM generation from a template with a warm tube syntax.
The library is called
SNC - Simple Node Creator. It does not manipulate the markup string (innerHTML in particular), but has its own very simple, understandable, and in many ways familiar syntax. At the input, it accepts a string — a pattern; the output is quite a ready-made
DocumentFragment .
')
The library is based on a lexical analyzer. Initially, the entire template is divided into an array of tokens. At the same time for the token separator its character code will be stored. This will make it possible to identify it unambiguously during an array search - by type. At the end we go through this sequence of tokens and collect the document.
Syntax
Any node description begins with its name. The name should be the name of the html tag. Then we decorators add various entities to the element.
.class
- add a class.
#id
add an id.
[...]
- allows you to specify nested nodes:
div.parent[ span.child ]
;
- node separator at one level:
ul.menu[ li#home; li#abount ]
ul.menu[ li#home; li#abount ]
:attr
is an empty attribute.
:attr@value
or
:attr=value
is one of the options for passing an attribute value. In this case, restrictions are imposed on the value - it should not contain the
#.[]:%@
Control characters. If the attribute name starts with “on”, then an event handler will be added, the name of the handler will be the value, and the body from the second argument. The handler will be added by standard means, dynamically. And if the name starts with "jq", then the jQuery event will be hung. The handler name can be set in two ways -
:onclick@handler
and
:onclick@%handler
- both of these methods have the same meaning.
%variable
is a universal way to set variables, as well as a way to transfer text data (html entities are transferred correctly). You can write
#%id
and then the attribute name will be taken from the second parameter - the value map. This is a simple object, where each key corresponds to a name in the template. Recently, it may be an array, the values ​​in this case are taken sequentially, as the template is processed. Such variables are supported for all basic elements - identifiers, classes, attributes and their values.
There is also a third parameter - it is responsible for preventing an exception from being generated if you suddenly forgot to specify the value of a variable. I do not recommend using it. In this case, “undefined” will be substituted for the missing values.
Using
Call the
SNC
function to which you pass the necessary parameters.
A few examples of patterns have been shown above. Here is another big example:
SNC("div #parent [" + "i.icon-open;" + "span.child%txt" + "] :data-status@%status" + ":onclick@handler" + ":jqcustomevent=jhandler", { txt:"lorem ipsum", status:1, handler:function(e){ console.log("Standart event"); }, jhandler:function(){ console.log("Custom event"); } });
Plans
The next development point will be the addition of cycles. I saw the syntax from Emmet. There will be something like this:
SNC("table [ {tr [ { td } * 2 ]} * 8 ]");
Also need to translate readme into English. But here I hope for the help of the community.
Rep:
github.com/ReklatsMasters/SNC