Modularize websites with Web Components
Web Perfect
Template Added
Line 1 of Listing 3 creates an initially empty HTML element of type <template>
and stores its reference in the local constant anotList
. Lines 2-12 initialize the template in declarative style, which means they specify an HTML code fragment in the form of a string. The script assigns the innerHTML
property to the string and copies it into the template.
Listing 3
anot-list.js (continued)
01 const anotList = document.createElement('template'); 02 anotList.innerHTML = ` 03 <style> 04 ul { 05 list-style: none; 06 padding:0; 07 } 08 </style> 09 <slot></slot> 10 <ul id='list'></ul> 11 <input id="text" type="text"> 12 <button id="add" type="button">+</button>`; 13 14 class AnotList extends AnotElement { 15 constructor() { 16 super(); 17 this.shadowRoot.appendChild(anotList.content.cloneNode(true)); 18 this.shadowRoot.querySelector('#add').addEventListener('click', e => this.addItem()); 19 this.listItem().forEach(text => this.showItem(text)); 20 } 21 22 addItem() { 23 let text = this.shadowRoot.querySelector('#text').value; 24 if (!this.hasItem(text)) { 25 this.saveItem(text); 26 this.showItem(text); 27 } 28 } 29 30 showItem(text) { 31 var listed = new AnotItem(text); 32 this.shadowRoot.querySelector('#list').appendChild(listed); 33 this.shadowRoot.querySelector('#text').value = ''; 34 this.shadowRoot.querySelector('#text').focus(); 35 } 36 }
Lists and Buttons
The entries in the <style>
tag format the HTML list in the <ul>
element in line 10. The list contains the saved comments. The <input>
element in line 11 enters new comments, and the <button>
element in the following line confirms the user input.
Line 17 of the constructor()
function for the class AnotList
, which starts in line 15, creates a copy of the template by cloning (cloneNode()
), which the script moves to the end of the shadow root by calling the appendChild()
method.
If the user has clicked on the aforementioned button, line 18 initiates the addItem()
callback function. Line 23 copies the value from the <input>
field and saves it in the text
variable.
If the call to the hasItem()
method together with the given value in line 24 of Listing 3 fails, line 25 saves the new comment text under localStorage
. Line 26 then visualizes it in the HTML document by calling the showItem()
method, which occurs in line 19 for each stored comment thanks to the calling constructor()
function.
Next, look at the showItem()
method (lines 30-35), which instantiates an object of the AnotItem
class in line 31. The listed
constant temporarily stores the returned reference to the list entry. The next line appends the cached element to the end of the HTML list (<ul id="list"/>
in line 10). Line 33 then empties the input field, and line 34 gives it the focus for further comments.
Slots
The <slot>
tag in line 9 now makes a late appearance. It takes on a special task and serves as an insertion mark for elements from outside in the shadow DOM standard, which plays that role in this example in line 9 of Listing 1 (i.e., <anot-title>My Comments</anot-title>
.
The AnotTitle
class resolves the user-defined element <anot-title>
in line 11 of Listing 4. The design pattern for <anot-list>
is used again when creating the Web Components. In line 9, the template uses <h3>
and another <slot>
tag, which causes the My Comments
text node from line 8 of Listing 1 to appear as a headline for the <anot-item>
added to the shadow DOM externally.
Listing 4
anot-list.js (continued)
01 const anotTitle = document.createElement ('template'); 02 anotTitle.innerHTML = ` 03 <style> 04 h3 { 05 margin: 0; 06 text-align:center; 07 } 08 </style> 09 <h3><slot></slot></h3>`; 10 11 class AnotTitle extends AnotElement { 12 constructor() { 13 super(); 14 this.shadowRoot.appendChild(anotTitle.content.cloneNode(true)); 15 } 16 }
Buy this article as PDF
(incl. VAT)