Official documentation link: Portal
Definition: Web Components is a set of technologies that allow you to create reusable custom elements whose functionality is encapsulated outside of your code and use them in your Web applications.
What it does: Web Components are used to make reusable components across technology stacks; Fundamentally solve CSS style global pollution problem.
The three elements:
- Custom Elements: A set of JavaScript apis that allow you to define Custom elements and their behavior, and then use them as needed in your user interface.
- Shadow DOM: A set of JavaScript apis for attaching a wrapped “Shadow” DOM tree to an element (rendered separately from the main document DOM) and controlling its associated functionality. This way, you can keep the functionality of elements private so that they can be scripted and styled without fear of running afoul of the rest of the document.
- HTML Templates (HTML Templates) : The template and slot elements allow you to write tag templates that are not displayed on rendered pages. They can then be reused many times as a basis for custom element structures.
Basic steps:
-
Create a class or function to specify the functionality of the Web component.
wordCount.html
<body> <h1>Word count rating widget</h1> <article contenteditable=""> Pellentesque ornare tellus sit amet massa tincidunt congue. Morbi cursus, tellus vitae pulvinar dictum, dui turpis faucibus ipsum, nec hendrerit augue nisi et enim. Curabitur felis metus, euismod et augue et, luctus dignissim metus. Mauris placerat tellus id efficitur ornare. Cras enim urna, vestibulum vel molestie vitae, mollis vitae eros. Sed lacinia scelerisque diam, a varius urna iaculis ut. Nam lacinia, velit consequat venenatis pellentesque, leo tortor porttitor est, sit amet accumsan ex lectus eget ipsum. Quisque luctus, ex ac fringilla tincidunt, risus mauris sagittis mauris, at iaculis mauris purus eget neque. Donec viverra in ex sed ullamcorper. In ac nisi vel enim accumsan feugiat et sed augue. Donec nisl metus, sollicitudin eu tempus a, scelerisque sed diam. <! -- <p is="word-count"></p>--> <word-count> </word-count> </article> </body> Copy the code
wordCount.js
class WordCount extends HTMLElement { constructor() { super(a);// The counter points to the parent let parent = this.parentNode; function countWords(node) { let text = node.innerText || node.textContent; return text.trim().split('/\s+/g') [0].length; }; let count = 'Words = ' + countWords(parent); Create the shadowRoot node const shadowRoot = this.attachShadow({mode: 'open'}); // Create a text node and add a counter let span = document.createElement('span'); // Add to shadowRoot shadowRoot.appendChild(span); // Start the timer to refetch the count every 200ms setInterval(() = > { count = 'Words = ' + countWords(parent); span.innerText = count; }, 200) } } customElements.define('word-count', WordCount); // Register new custom elements Copy the code
-
Using CustomElementRegistry. Define () method to register the new custom elements. Accepts the element name defined by three parameters, the class specifying the element’s functionality, and the optional options option for the element it inherits from
-
Use of shadow DOM. Attach a shadow DOM to the custom Element using the element.attachShadow () method. Add child elements, event listeners, and so on to the Shadow DOM using the usual DOM methods
The following code mainly shows the pit of the third parameter’s option when used.
wordCount.html
<body>
<h1>Word count rating widget</h1>
<article contenteditable="">
Pellentesque ornare tellus sit amet massa tincidunt congue. Morbi cursus, tellus vitae pulvinar dictum, dui turpis faucibus ipsum, nec hendrerit augue nisi et enim. Curabitur felis metus, euismod et augue et, luctus dignissim metus. Mauris placerat tellus id efficitur ornare. Cras enim urna, vestibulum vel molestie vitae, mollis vitae eros. Sed lacinia scelerisque diam, a varius urna iaculis ut. Nam lacinia, velit consequat venenatis pellentesque, leo tortor porttitor est, sit amet accumsan ex lectus eget ipsum. Quisque luctus, ex ac fringilla tincidunt, risus mauris sagittis mauris, at iaculis mauris purus eget neque. Donec viverra in ex sed ullamcorper. In ac nisi vel enim accumsan feugiat et sed augue. Donec nisl metus, sollicitudin eu tempus a, scelerisque sed diam.
<p is="word-count"></p>
</article>
</body>
Copy the code
class WordCount extends HTMLParagraphElement {
constructor() {
super(a);// The counter points to the parent
let parent = this.parentNode;
function countWords(node) {
let text = node.innerText || node.textContent;
return text.trim().split('/\s+/g') [0].length;
};
let count = 'Words = ' + countWords(parent);
Create the shadowRoot node
const shadowRoot = this.attachShadow({mode: 'open'});
// Create a text node and add a counter
let span = document.createElement('span');
// Add to shadowRoot
shadowRoot.appendChild(span);
// Start the timer to refetch the count every 200ms
setInterval(() = > {
count = 'Words = ' + countWords(parent);
span.innerText = count;
}, 200)
}
}
customElements.define('word-count', WordCount, { extends: 'p' }); The third argument is that the custom element inherits from the p tag
Copy the code
Additional use:
- The use of the template
The template element is a mechanism for holding client-side content that is not rendered when the page loads, but can then be instantiated at run time using JavaScript.
- The use of slot is a placeholder within Web Components as part of the Web Components technology suite. This placeholder can be filled in later in your own markup language so that you can create a separate DOM tree and combine it with other components.
Full example (full example shows how template and slot are used) :
WordCount.html
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#innerSpan {
color: blue ! important;
}
#innerp {
color: blue ! important;
}
</style>
</head>
<body>
<h1>Word count rating widget</h1>
<article contenteditable="" onclick="Test()">
Pellentesque ornare tellus sit amet massa tincidunt congue. Morbi cursus, tellus vitae pulvinar dictum, dui turpis faucibus ipsum, nec hendrerit augue nisi et enim. Curabitur felis metus, euismod et augue et, luctus dignissim metus. Mauris placerat tellus id efficitur ornare. Cras enim urna, vestibulum vel molestie vitae, mollis vitae eros. Sed lacinia scelerisque diam, a varius urna iaculis ut. Nam lacinia, velit consequat venenatis pellentesque, leo tortor porttitor est, sit amet accumsan ex lectus eget ipsum. Quisque luctus, ex ac fringilla tincidunt, risus mauris sagittis mauris, at iaculis mauris purus eget neque. Donec viverra in ex sed ullamcorper. In ac nisi vel enim accumsan feugiat et sed augue. Donec nisl metus, sollicitudin eu tempus a, scelerisque sed diam.
<! -- <p is="word-count"></p>-->
<word-count>
<ul slot="element-name">
<li>Let's have some different text!</li>
<li>In a list!</li>
</ul>
</word-count>
</article>
<template id="testHtml">
<style>
div {
color: white;
width: 100%;
height: 200px;
background-color: # 666;
padding: 5px;
}
</style>
<div>
<slot name="element-name"></slot>
</div>
</template>
<script src="WordCount.js"></script>
<script>
function Test() {
console.log(232323)}</script>
</body>
</html>
Copy the code
WordCount.js
class WordCount extends HTMLElement {
// class WordCount extends HTMLParagraphElement {
constructor() {
super(a);// The counter points to the parent
let parent = this.parentNode;
function countWords(node) {
let text = node.innerText || node.textContent;
return text.trim().split('/\s+/g') [0].length;
};
let p = document.createElement('p');
this.parentNode.appendChild(p)
p.setAttribute('id'.'innerp');
p.innerText = 'test';
p.style.color = 'red';
let count = 'Words = ' + countWords(parent);
Create the shadowRoot node
const shadowRoot = this.attachShadow({mode: 'open'});
// Create a text node and add a counter
let span = document.createElement('span');
let button = document.createElement('button');
span.innerText = count;
span.setAttribute('id'.'innerSpan');
span.style.color = 'red';
button.innerText = 'am I';
// Add to shadowRoot
shadowRoot.appendChild(span);
shadowRoot.appendChild(button);
button.onclick = function() {
console.log(`count is ${count}`)}// button.addEventListener('click', function () {
// console.log(`count is ${count}`)
// },false)
// Check to see if the browser supports HTML template elements
// Used to hold the content attributes of the template element.
if ('content' in document.createElement('template')) {
// Use existing HTML tBody to instantiate tables and rows and templates
let t = document.getElementById('testHtml')
// Clone the new row and insert it into the table
shadowRoot.appendChild(t.content.cloneNode(true));
} else {
// Find another way to add rows to the table, as HTML template elements are not supported.
}
// Start the timer to refetch the count every 200ms
setInterval(() = > {
count = 'Words = ' + countWords(parent);
span.innerText = count;
}, 200)}}// customElements.define('word-count', WordCount, { extends: 'p' });
customElements.define('word-count', WordCount);
Copy the code