⬆️ ⬇️

Modern Web-platform: how to relax and have fun? A practical guide, part 1

Hello!



Remember this article ? Previously, we could quickly collect a static HTML-page in some FrontPage and the site was ready. Any student could cope with this. In a more complicated case, we wrote a couple of lines in PHP and already received a whole portal compiled from different template elements on the server. Then we wanted our site to somehow stand out against the general background and be able to slightly more. The throne was occupied by his majesty jQuery. Now, we are buried under the rubble of frameworks and libraries, build tools, dependency managers, preprocessors and postprocessors, special formats, languages ​​and programming styles to be able to concoct simple landing pages. Everything has become too difficult. Speakers at conferences began to compete in the sophistication of how else we can break our brains. How have we come to such a life? How is “earlier” so different from “now”? What awaits us "later"? Is there some kind of Zen-style in modern web development, observing that you can, like in the good old days, assemble yourself a cozy saytik “on your knee” for a couple of evenings, without picking up a dozen hipster technologies? How simple solutions are available to us in serious industrial development? Where is the web platform going? I suggest to understand.



In order to experiment with the practical part, you will need any convenient code editor (for example, Visual Studio Code ) and the current version of the Chrome browser . For starters, this will be quite enough. Subsequently (I am planning a whole cycle of publications on this topic), everything will inevitably become more complicated, but we will try to remain “within the framework” - this is our goal.



Background and Solution



When I made my first sites (in the late 90s - early 2000s), the first thing that seemed strange and awkward in ordinary HTML was the inability to describe the site’s header, footer and main menu in one place for all pages at once. I could insert one image or one script in many places, but not a trivial piece of markup. Also, I could not describe the overall page layout, without the need to repeat it in each individual HTML file. I think many of these same reasons pushed for the first experiments with server technologies. But for the entire server, an appropriate server is needed, and this is a new level of task complexity, which at first seemed so simple. Anyway, this problem has been solved many times and in many ways. We tried to use an iframe, tried to dynamically control the visibility of fragments contained on the same page; as soon as they did not mock themselves and common sense. As a result, we have come to a modern set of meta-platforms such as React or Vue.js, which, among other things, allow us to create a structure of modules reflecting the structure of what we see on the screen. But the web platform itself does not stand still and, oh, a miracle, now we have a native ability to create more than just reusable pieces of markup: now we can create our own real HTML tags! Moreover, each such tag can be either a primitive container containing only the necessary design (or be an interactive UI element), or a layout of the entire page. It can even contain a whole complex application with a bunch of client-server logic you need. Yes, I'm talking about the new Standard Custom Elements (Living Standard). And he really changes a lot.



We taste



For the first acquaintance, let's reproduce the above case with a general layout, header, footer and navigation menu, in the most primitive form:

')

Index.html file:



<html> <head> <script src="elements/my-layout.js"></script> <script src="elements/my-header.js"></script> <script src="elements/my-footer.js"></script> <script src="elements/my-menu.js"></script> </head> <body> <my-layout> <my-header slot="header">Hi, I am your header.</my-header> <div slot="content">Hello World! This is content.</div> <my-menu slot="menu"></my-menu> <my-footer slot="footer">And I am your footer.</my-footer> </my-layout> </body> </html> 


Pay attention to the naming of custom tags: according to the standard, it must contain a hyphen (one or more). Also, you probably noticed the attribute "slot" - about him a little later.



Now let's move on to the file that describes the main layout of the elements / my-layout.js page :



 class MyLayout extends HTMLElement { constructor() { //     HTMLElement: super(); // C ShadowDOM  -  , //      ,    JS: this.attachShadow({ mode: 'open', }); //     : this.shadowRoot.innerHTML = ` <style> :host { display: block; } .header { position: fixed; top: 0; left: 0; right: 0; height: 40px; line-height: 40px; padding-left: 20px; padding-right: 20px; background-color: #000; color: #fff; } .menu { position: fixed; top: 0; bottom: 0; right: 0; width: 240px; padding: 20px; background-color: #eee; box-shadow: 0 0 8px rgba(0, 0, 0, 0.4); z-index: 1000; } .content { padding-top: 60px; padding-bottom: 60px; } .footer { position: fixed; left: 0; right: 0; bottom: 0; height: 40px; line-height: 40px; padding-left: 20px; padding-right: 20px; background-color: #eee; border-top: 2px solid #000; } </style> <div class="header"><slot name="header"></slot></div> <div class="content"><slot></slot></div> <div class="menu"><slot name="menu"></slot></div> <div class="footer"><slot name="footer"></slot></div> `; } } //   : window.customElements.define('my-layout', MyLayout); //        <my-layout>. 


I apologize for the excess styles in this example: they are needed only for clarity when displaying the result in the browser.



In the part of the template where the markup itself is located, we again meet the word “slot” - this is a special tag that works in conjunction with ShadowDOM - it defines the position in the markup for the content parts of our element. Compliance is determined by the very attribute "slot", which I mentioned earlier. If the tag “slot” does not have the attribute “name” - the content “by default” will fall into it, which, in turn, does not have the attribute “slot”. This is a very simple, but very powerful native templating tool on the "client side".



Hostess note
VS Code - is not able to automatically highlight the HTML syntax inside an ES6 string. To work with large sections of the markup inside JS-files, you can temporarily switch the syntax of the open file to HTML mode (lower right corner of the window): you will be available to highlight, hints and auto-completion in HTML and CSS.



Create the remaining elements. Elements / my-menu.js file :

 class MyMenu extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open', }); this.shadowRoot.innerHTML = ` <style> :host { display: block; } a { display: flex; align-items: center; justify-content: center; background-color: #fff; cursor: pointer; height: 40px; text-decoration: none; color: currentColor; font-size: 1.2em; margin-bottom: 4px; border: 1px solid #fff; } a:hover { border: 1px solid currentColor; } </style> <a href="pages/page1.html">Page 1</a> <a href="pages/page2.html">Page 2</a> <a href="pages/page3.html">Page 3</a> `; } } window.customElements.define('my-menu', MyMenu); 


The elements / my-header.js file :



 class MyHeader extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open', }); this.shadowRoot.innerHTML = ` <style> :host { display: block; } span { font-size: 0.8em; opacity: 0.6; } </style> <span>Text inside ShadowDOM.  </span> <slot></slot> `; } } window.customElements.define('my-header', MyHeader); 


And the last file of our nano-project elements / my-footer.js :



 class MyFooter extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open', }); this.shadowRoot.innerHTML = ` <style> :host { display: block; } ::slotted(*) { display: inline-block; } span { color: #f00; font-size: 0.8em; } </style> <slot></slot> <span> © 2018, Vasya Pupkin</span> `; } } window.customElements.define('my-footer', MyFooter); 


Ta-dam! You can open our index.html in the browser. The attentive reader noted that the styles for the “span” tag were directly identified in two places at once (for different elements), but they did not affect each other and were displayed correctly.



What did we see?



We saw an example of a real modular development without connecting any external libraries, without setting up the environment, without waiting for the build of the project, even without the need to run a local server. In the browser’s developer tools, we see directly our JS code and our own markup, and not the output of the scripts that create the DOM for us. The content of our main HTML file is in it and immediately accessible, again, without any prior rendering. We can reuse our custom tags in this same project or in any other. We did not download anything extra and displayed the page almost instantly. The amount of additional JS-code that we needed for this is microscopic. At the same time, each of our new element is the same full DOM element as any standard div. The same standard attributes, properties, events, and methods like addEventListener, appendChild, remove, etc. are available to it. Is this what we wanted for so long? Yes, I think so.



Further more



In the future, we will consider the following topics (not necessarily in the specified order):





Thanks for attention!

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



All Articles