📜 ⬆️ ⬇️

A review of the new javascript framework Htmlix

In this article I will try to describe all the main features of the new javascript framework Htmlix, as well as consider the principle of its work on the example of creating a small application.

This application is a simple filter page of products by category, with different parts of the template in the product card.

A full example of this application, as well as others, can be viewed at the link on the githaba:
')
Link to examples, this example: page-template.html, /js/page-template.js

Wiki with a list of all standard properties and methods of the application can be viewed
here

The working application example can be clicked here.

More easy to understand code can be viewed at the link:
Htmlix Step-by-Step Guide to Creating Items

Htmlix is ​​a micro framework for building frontend in javascript. The principle of its work is based on data-attributes.

The essence of his work is that we use the data-properties to create the structure of the application in the html file by adding properties, event handlers and listeners.
And then we list their names in the js code (to get access to them), the creation of all objects and event attachments occurs automatically by defining the data types attached to the data properties.

It is easier to simply look at the code of the finished example. To understand how everything works, this article provides a brief description of the process of creating the structure of the application.

To get started in the html file, a preliminary description of the structure of the application is made by attaching data attributes with an indication of their type (attribute type in quotes),
eg:

<div class=" row" data-cards="array" data-cards-listenfetch="emiter-fetch-posts" data-cards- listenrout="emiter-router" data-cards-displayall="style"> <div data-card="container" class="col-4 card-in"> <h5 data-card-title="text"> 1</h5> <a data-card-click="click" data-card-href="href" href="/page/card?id=0"> <img data-card-srcimg="src" src="/img/images.jpg" /> </a> <p data-card-paragraf="text">  1</p> </div> <div data-card="container" class="col-4 card-in"> <h5 data-card-title="text"> 2</h5> <a data-card-click="click" data-card-href="href" href="/page/card?id=1"> <img data-card-srcimg="src" src="/img/Thumbnail_300x300.png" /> </a> <p data-card-paragraf="text">  2</p> </div> ....................... 


Here:
data-cards = “array” - create an array of similar elements
data-card = "container" - containers are a set of elements of the same type, or it is one element
if it is not placed in an array, the containers contain all the mutable and received properties, as well as event handlers and event listeners.
data-card-title = "text" - a property that contains access to the text from javscript (this.title.getProp (), .setProp ())
data-card-click = "click" - attaches a click event handler to this tag.
data-cards-listenfetch = "emiter-fetch-posts" - attaches the handler for the user event "emiter-fetch-posts" to the container property.

Custom events notify all properties to which they are attached by calling a function from any part of the code with the name of the event. For example, this.eventProps ["emiter-fetch-posts"]. SetProp ("posts") - will trigger on all listeners an event "emiter-fetch-posts" in which it will be possible to get the modified data "posts".

For properties containing standard events, there are also two additional methods, disableEvent () and enableEvent (), turning off and on the event on a specific element (in order not to delete it completely).

All properties are contained in containers (data-card = "container"), if these are containers of the same type and need to be added or deleted during the operation of the application, they are grouped into arrays (data-cards = "array").

Properties are named as follows: after data comes the name of the container in which this property is stored, then comes the name of the property or function, then after the = sign in quotes the type of this property, for example “class”, if this event is written the name of the event, for example “click” if this is a custom event, then “emiter-next event name”, for example “emiter-fetch-posts”. When creating a property object, the type is important in order to determine what needs to be done with this property. If this event is, it will search for the function of the same name and add the appropriate handler.

The container located in the array can be removed by calling the .remove () method or from the root application by id by calling this.rootLink.removeByIndex (nameArray, id), the container id is its order number in the array and can change when adding or removing neighboring containers.

Next, after adding all the properties and determining the structure of the application in html, the application is described in javascript, by listing all the names of arrays, containers, properties, and methods of event handlers, for example:

 var State = { cards:{ /*   (data-cards="array") */ container: 'card', /*   (data-card="container"),          */ arrayProps: ["listenrout", "listenfetch", "displayall"], /*        html   (data-cards-displayall="style")*/ arrayMethods: { /*   */ listenrout: function(){ /*   ["emiter-router"] ( html - listenrout="emiter-router") */ if(this.emiter.prop == "/page-template.html"){ /*    */ this.parentContainer.props.displayall.setProp("") /*         ,     */ }else{ this.parentContainer.props.displayall.setProp("display: none;") } }, listenfetch: function(){ /*   ["emiter-fetch-posts"] ( html - listenrout="emiter-fetch-postsr") */ var newArray = this.emiter.prop; this.rootLink.clearContainer(this.pathToContainer); for(var i =0; i< newArray.length; i++){ this.rootLink.createContainerInArr(this.pathToContainer, { /*            */ title: newArray[i].title, paragraf: newArray[i].paragraf_short, href: newArray[i].href, srcimg: newArray[i].srcimg }); } this.rootLink.stateProperties.cards = newArray; /*      */ } }, props: ['title','paragraf',"click", 'srcimg', "href"], /*        html   */ methods: { click: function(event){ <!--   click (data-card-click="click")--> event.preventDefault(); var href = this.parentContainer.props.href.getProp(); /*   (data-card-href="href")          */ var cardId = href.split("?")[1].split("=")[1]; window.history.pushState( null, href, href ); /*          */ this.rootLink.eventProps["emiter-router"].setEventProp(href); this.rootLink.eventProps["emiter-single-id"].setEventProp(cardId); } } }, ....................... 

User events must also be registered in the object description, example:

  eventEmiters: { ["emiter-router"]: { /*      */ prop: "/page-template.html" }, ["emiter-single-id"]: { prop: "0" }, ["emiter-fetch-posts"]: { prop: "", }, 

Then when calling for example: this.rootLink.eventProps ["emiter-router"]. SetEventProp (href);
all listeners of the [“emiter-router”] event (listenrout = “emiter-router” - in html code) will be able to get new data in their handlers and update themselves based on them, as in the code below:

  listenrout: function(){ /*   ["emiter-router"] ( html-listenrout="emiter-router") */ if(this.emiter.prop == "/page-template.html"){/*    */ this.parentContainer.props.displayall.setProp(""); /*         ,     */ }else{ this.parentContainer.props.displayall.setProp("display: none;") } }, 

You can also add static variables to the description (variables that do not call event handlers when they change):

  stateProperties: { cards: "", }, 

Common to the whole application methods:

  stateMethods: { fetchPosts: function(nameFile, callb){ fetch('/json/'+nameFile+'.json') .then((response) => { if(response.ok) { return response.json(); } throw new Error('Network response was not ok'); }) .then((json) => { callb(json); }) .catch((error) => { console.log(error); }); }, }, 

Components that will be loaded asynchronously from the html of the components template (template.html)

  fetchComponents: { variants1: { /*     ,     /templete/template.html */ container: "variant1", props: ["clickvariant", "text"], methods: { clickvariant: function(event){ event.preventDefault(); this.rootLink.eventProps["emiter-chose-variant"].setEventProp(this.parentContainer.props.text.getProp()); //console.log(this); }, } }, 

An instance of the application is created using the function:

 window.onload = function (){ var HM = new HTMLixState(State); /*    */ HM.stateMethods.fetchPosts('category1', function(jsonData){ HM.stateProperties.cards = jsonData }); console.log(HM); } 

In the console you can see the structure of the created object where:



This was a quick overview of creating an application, on htmlix.

The framework itself has an object-oriented structure, where each property is an object. Obtaining, writing and deleting properties is done using the setProp (), getProp () and removeProp () methods, depending on the type of property, the application itself determines how it changes this property in html, if this class is called this function. htmlLink.classList.add ("class").

There are not so many methods in the framework, you can get acquainted with them by looking at the source code where there is a brief description of the main ones used during the work. Therefore, for those who know javscript well, it should not be a big deal to figure out. So far, htmlix is ​​in the test version, but now with the help of it you can solve many typical frontend development tasks.

Source: https://habr.com/ru/post/456454/


All Articles