Modularize websites with Web Components
Web Perfect
Modular
For some time now, the JavaScript [10] module system from the HTML specification has replaced HTML imports when loading the Web Components. To upgrade missing features in the browser, line 4 of the HTML document in Listing 1 loads the webcomponentsjs
polyfills via a <script>
tag.
This URL offers all modules from Node's official package archive [11]. You can refine the selection by specifying certain operators. The web page loads the package if the name is followed by @1.0.16
.
The code that resolves the <anot-list>
and <anot-title>
user-defined tags is loaded in line 5 of Listing 1. In line 11, the code saves the sample text in the HTML5 <article>
tag.
Shadowy
The JavaScript code generates the Web Components by evaluating the function call in the (function(){
…})
expression (Listing 2, lines 1-6). The anonymous function block prevents the constants, variables, and classes declared in the listings from falsifying the global namespace of the JavaScript environment by overwriting it.
Listing 2
anot-list.js
01 (function() { 02 class AnotElement extends HTMLElement { 03 constructor() { 04 super(); 05 this.attachShadow({'mode': 'open'}); 06 } 07 08 listItem() { 09 const arr = JSON.parse(window.localStorage.getItem('annotations')); 10 return arr?arr:[]; 11 } 12 13 hasItem(text) { 14 return text == '' || this.listItem().filter(stext => text === stext).length > 0; 15 } 16 17 saveItem(text) { 18 if (!this.hasItem(text)) { 19 const arr = this.listItem(); 20 arr.push(text); 21 window.localStorage.setItem('annotations', JSON.stringify(arr)); 22 } 23 } 24 25 delItem(text) { 26 const arr = this.listItem().filter(stext => text !== stext); 27 localStorage.setItem('annotations', JSON.stringify(arr.length>0?arr:[])); 28 } 29 }
The <anot-list>
, <anot-title>
, and <anot-item>
tags defined by the developer are first declared as classes in Listings 3-5, respectively. The parent class AnotElement
(Listing 2) is derived from the built-in HTMLElement
class.
The constructor()
function of AnotElement
instantiates a shadow root as the root element for the shadow DOM associated with the host element (Listing 2, line 5). It calls the attachShadow()
method and stores its reference implicitly in the shadowRoot
property.
Stored Locally
The methods in Listing 2 give each class instance an API to store the application data. The interface uses the localStorage
browser object to store the data under the local browser instance in the form of a serialized field for the annotations
key (line 9). For serializing, Listing 2 uses the stringify()
method to deserialize the parse()
method of the global JSON object (line 9). At this point, the listItem()
method reads the serialized field with getItem()
from localStorage
and converts it to an array. Line 10 ensures that a field is returned.
The hasItem()
method tests the stored field for duplicates in lines 13-15. The filter()
array method searches the list for hits, and saveItem()
saves a new comment from the call parameter text
(line 17). To do this, line 20 appends the value of text
to the list of existing comments, and line 21 serializes the extended list and writes it back to localStorage
by calling the setItem()
method.
An almost identical expression is used in line 27, which saves the list cleaned up by calling the delItem()
method (lines 25-28) in localStorage
again. The filter()
in line 26 sifts through the text
object that is passed in.
Buy this article as PDF
(incl. VAT)