Create inline CSS and JavaScript Custom Elements by using Custom Elements. It’s important to note that it’s not an alternative to React, Vue, or Angular frameworks; it’s a completely new concept.
Create a completely custom element
CustomElementRegistry object
The customElements attribute is exposed under the Window global object, through which the CustomElementRegistry object can be accessed. There are several methods under the CustomElementRegistry object to register Custom Elements and query Custom Elements:
define()
Use to define a new Custom Elementget()
Constructor for getting a Custom Element, returning undefined if none existsupgrade()
Used to upgrade Custom ElementswhenDefined()
Constructor for getting Custom elements, similar to get() except that the return value is promise and the available values return at this point or at this point
How do I create a Custom Element
In the call window. CustomElements. Define () method before, first of all to define a new HTML element
class CustomTitle extends HTMLElement {
// ToDo...
}
Copy the code
Use the Shadow DOM in the constructor of the CustomTitle class to associate custom CSS, JavaScript, and HTML to the new element, so that you can encapsulate various functions in this new element, first initializing the constructor
class CustomTitle extends HTMLElement {
constructor() {
super(a)/ /...}}Copy the code
AttachShadow () is then called with the parameter {mode: ‘open’}. This attribute sets the encapsulation mode of the shadow DOM. If it is set to open, access to the element’s shadowRoot attribute is available, but if it is set to close, it is not.
class CustomTitle extends HTMLElement {
constructor() {
super(a)this.attachShadow({ mode: 'open' })
/ /...}}Copy the code
Next, set the HTML for the element
class CustomTitle extends HTMLElement {
constructor() {
super(a)this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = ` Hello WC!
`}}Copy the code
The innerHTML here can write multiple HTML tags
Once you have defined the built-in elements, use window.customElements
window.customElements.define('custom-title', CustomTitle)
Copy the code
The above can be used in the page
Add CSS
class CustomTitle extends HTMLElement {
constructor() {
super(a)this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = ` Hello WC!
`}}Copy the code
Shorthand syntax
window.customElements.define('custom-title'.class extends HTMLElement {
constructor() {... }})Copy the code
Add JavaScript
The method of adding JavaScript is slightly different from that of CSS. It cannot write directly into the template string, but needs to add addEventListener
class CustomTitle extends HTMLElement {
constructor() {
super(a)this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = ` Hello WC!
`
this.addEventListener('click', e => {
console.log('clicked')}}}Copy the code
The demo link
Use the template
You can use template, specified by id to
<template id="custom-title-template">
<style>
h1 {
font-size: 40px;
color: # 000;
}
</style>
<h1>Hello WC!</h1>
</template>
<custom-title></custom-title>
Copy the code
It then references the Shadow DOM in the Custom Element constructor
class CustomTitle extends HTMLElement {
constructor() {
super(a)this.attachShadow({ mode: 'open' })
const tmpl = ducument.querySelector('#custom-title-template')
this.shadowRoot.appendChild(tmpl.content.cloneNode(true))}}window.customElements.define('custom-title', CustomTitle)
Copy the code
The demo link
The life cycle
In addition to constructor, you can define lifecycle functions that execute a particular method at a particular time
connectedCallback
Executed when the element is inserted into the DOMdisconnectedCallback
Executed when an element is deleted from the DOMattributeChangedCallback
Executed when a change or addition or deletion of a property is detected (passing in 3 parameters)- AttrName: Changed attribute name
- OldVal: the value before the property changed
- NewVal: the changed value of the property
adoptedCallback
When the element hasWhen moving to a new document
class CustomTitle extends HTMLElement {
constructor() {
/ /...
}
connectedCallback() {
/ /...
}
disconnectedCallback() {
/ /...
}
attributeChangedCallback(attrName, oldVal, newVal) {
/ /...}}Copy the code
As mentioned above, attributeChangedCallback listens for changes in attribute values. To define the range of listening attribute values, you must define a static method that returns an array of listening attributes
class CustomTitle extends HTMLELement {
constructor() {
/ /...
}
static get observedAttributes() {
return ['diabled']
}
attributeChangedCallback() {
/ /...}}Copy the code
Here I define the disabled property to be listened on when its value changes, such as when its value is true
document.querySelector('custom-title').disabled = true
Copy the code
At this point, attributeChangedCallback is triggered, with the three parameters ‘disabled’, false, and true, respectively
Define custom properties
Define custom properties on custom elements by adding getter and setter functions to define custom properties on custom elements
class CustomTitle extends HTMLElement {
static get observedAttributes() {
return ['nbattribute']
}
get nbattribute() {
return this.getAttribute('nbattribute')
}
set nbattribute(value) {
this.setAttribute('nbattribute', value)
}
}
Copy the code
If a Boolean property value such as disabled is defined, the property value is displayed if true and not if false
class CustomTitle extends HTMLElement {
static get observedAttributes() {
return ['boolattribute']
}
get boolattribute() {
return this.hasAttribute('boolattribute')
}
set boolattribute(value) {
if (value) {
this.setAttribute('boolattribute'.' ')}else {
this.removeAttribute('boolattribute')}}}Copy the code
Styles custom elements that have not yet been defined
During page loading, JavaScript takes time to load and custom elements are not yet defined. When the page is loaded, the layout of the page may not be so friendly. To solve this problem, add :not(:defined) pseudo-classes and set a rough height and gradient effect
custom-title:not(:defined) {
display: block;
height: 400px;
opacity: 0;
transition: opacity 0.5 s ease-in-out;
}
Copy the code
Browser Supportcaniuse
Latest versions of FireFox, Safari, Chrome, Edge rewritten with Chromium kernel, IE (forget it), and polyfill for older browsers
Create built-in elements for customization functionality
The essence element of the so-called customization function refers to the customization function of the existing elements in HTML and the extension of the existing elements. Attach features such as constructors and lifecycle hooks to existing elements. Creating custom built-in elements is different from fully custom elements, as shown below. To extend Button functionality, first you need to define a class that inherits HTMLButtonElement instead of HTMLElement
class PlasticButton extends HTMLButtonElement {
constructor() {
super(a)this.addEventListener('click', e => {
// Do something }}})// When you define a custom element, you add the extends parameter
customElement.define('plastic-button', PlasticButton, { extends: 'button' })
Copy the code
There is also a difference in usage, using the IS attribute on the original element to specify the extended element
<button is="plastic-button"></button>
Copy the code
Browser Supportcaniuse
Latest versions of FireFox, Safari, Chrome, Edge rewritten with Chromium kernel, IE (forget it), and polyfill for older browsers
Web Components related libraries
- Hybrids is a UI library for creating Web Components with simple and functional API.
- LitElement uses lit-html to render into the element’s Shadow DOM and adds API to help manage element properties and attributes. Polymer provides a set of features for creating custom elements.
- Slim.js is an opensource lightweight web component library that provides data-binding and extended capabilities for components, using es6 native class inheritance.
- Stencil is an opensource compiler that generates standards-compliant web components.
reference
- www.webcomponents.org/introductio…
- The w3c. Making. IO/webcomponen…