Create custom HTML elements
We can use document. registerElement () creates a custom HTML element. This function returns a constructor. The first parameter is used to declare the name of the custom HTML element, and the second parameter is optional, the object used to describe the prototype and the elements of the custom function.
In the following example, a new HTML element <x-treehouse> is created and put into the page:
Var XTreehouseElement = document. registerElement ('x-treehouse ');
Document. body. appendChild (new XTreehouseElement ());
The following HTML is inserted into the <body> element:
<X-treehouse> </x-treehouse>
The name of a custom element must use a hyphen (-), so that the browser can distinguish between standard and custom elements. This also means that you will not encounter a new HTML element with the same name as your custom element.
Create JavaScript API for custom elements
You can create a JavaScript API for a custom element so that the custom element has a series of methods and attributes. To do this, you must first create a JavaScript object. You can use the Object. create () method. Pass HTMLElement. prototype to this method and create an object. The method and attribute of this object and standard HTML are the same.
Var XTreehouseProto = Object. create (HTMLElement. prototype );
You can define the methods you need on this new object as follows:
XTreehouseProto. hello = function (){
Alert ('Hello! ');
}
Use the Object. defineProperty () method to define an attribute for a custom element. The first parameter of this method is the object for defining attributes, the second parameter is the name of the attribute to be defined or modified, and the third parameter is the descriptor of the attribute to be defined or modified. Here you can set a default value to specify whether the attribute is writable or readable.
Object. defineProperty (XTreehouseProto, 'badges ',{
Value: 20,
Writable: true
});
Once an API is defined for a custom element, it must be called using document. registerElement. Use the name of the custom element as the first parameter, and then set the object to a property named prototype. The value of this attribute should be set to the prototype object you created earlier.
Var XTreehouseElement = document. registerElement ('x-treehouse ',{
Prototype: XTreehouseProto
});
Once a custom element is registered, you can create a new element and add it to the page.
Var xtreehouse = new XTreehouseElement ();
Document. body. appendChild (xtreehouse );
You can use the previously defined methods and attributes like other HTML elements.
Xtreehouse. hello ();
Var badges = xtreehouse. badges;
Extend existing elements
Just like the custom elements created, you can also use the registerElement () method to extend the functions of existing HTML elements. For example, you can extend the element to create a thumbnail display with variables.
Create an object prototype as before. However, this time, the object prototype is extended from the existing HTML elements. In this example, the extension is HTMLImageElement.
Var ThumbImageProto = Object. create (HTMLImageElement. prototype );
Next, use createCallback to define a function (callback function). When creating an element, the width and height of the image are defined.
ThumbImageProto. createdCallback = function (){
This. width = '000000 ';
This. height = '20180101 ';
};
You can also customize your own attributes and methods:
ThumbImageProto. changeImage = function (){
This. src = 'new-image.jpg ';
};
When you want to expand an element and create an element in document. registerElement (), you can add the extends attribute to the object. The attribute value is the name of the element to be extended.
Var ThumbImage = document. registerElement ('thumb-img ',{
Prototype: ThumbImageProto,
Extends: 'IMG'
});
To use a custom element, you can specify an attribute for the element to expand the element. The value of this attribute is the name of the custom element. You can tell the browser that uses the custom API: thumb-img.
Custom element callback method
Many callback methods can be used to create and manage custom elements:
CreatedCallback: called after an element is created
AttachedCallback: called after an element is attached to a document
DetachedCallback: call
AttributeChangedCallback (attrName, oldValue, newValue): called after any attribute of the element is changed
Specify the prototype objects of these callback functions and pass them to document. registerElement ().
Var XTreehouseProto = Object. create (HTMLElement. prototype );
XTreehouseProto. createdCallback = function (){}
XTreehouseProto. attachedCallback = function (){}
XTreehouseProto. detachedCallback = function (){}
XTreehouseProto. attributeChangedCallback = function (attrName, oldValue, newValue ){}
Var XTreehouse = document. registerElement ('x-treehouse', {prototype: XTreehouseProto });
Use Shadow DOM to create custom elements
The real power of custom elements is how to use them with the Shadow DOM. This makes it easy to create reusable components.
In the following content, we will see how to use the Shadow DOM custom element to create a product that can be displayed in an online store. The idea here is that Web developers can easily create products by adding a line of HTML tags. All the information of the production Port to be displayed is completed through the custom data-attribute.
<X-product data-name = "Product Name" data-img = "image.png" data-url = "http://example.com"> </x-product>
Create a new prototype object based on HTMLElement. prototype.
// Create a new object based on the HTMLElement prototype
Var XProductProto = Object. create (HTMLElement. prototype );
Next, we need to set a createdCallback function. We will create a and <a> element to display the product. First, the code is displayed, and then detailed introduction:
// Set up the element.
XProductProto. createdCallback = function (){
// Create a Shadow Root
Var shadow = this. createShadowRoot ();
// Create an img element and set it's bubutes.
Var img = document. createElement ('IMG ');
Img. alt = this. getAttribute ('data-name ');
Img. src = this. getAttribute ('data-img ');
Img. width = '000000 ';
Img. height = '000000 ';
Img. className = 'product-img ';
// Add the image to the Shadow Root.
Shadow. appendChild (img );
// Add an event listener to the image.
Img. addEventListener ('click', function (e ){
Window. location = this. getAttribute ('data-url ');
});
// Create a link to the product.
Var link = document. createElement ('A ');
Link. innerText = this. getAttribute ('data-name ');
Link. href = this. getAttribute ('data-url ');
Link. className = 'product-name ';
// Add the link to the Shadow Root.
Shadow. appendChild (link );
};
First, create a new Shadow DOM. If you are not familiar with the Shadow DOM, read the previous article. Create an element and set its alt, src, width, and height attributes to specify information about the x-product element.
Note: this refers to the tag of custom elements.
Next, add the and <a> elements to the Shadow root. And set the element property value to get from the data-attribute of the custom element.
Now we need to register custom elements, and pass the x-product element to document. registerElement (), and specify the object prototype as XProductProto:
// Register the new element.
Var XProduct = document. registerElement ('x-product ',{
Prototype: XProductProto
});
To make the project display better, you need to add some CSS code:
X-product {
Display: inline-block;
Float: left;
Margin: 0.5em;
Border-radius: 3px;
Box-shadow: 0 1px 3px rgba (0, 0, 0, 0.3 );
Font-family: Helvetica, arial, sans-serif;
-Webkit-font-smoothing: antialiased;
}
X-product: shadow. product-img {
Cursor: pointer;
Background: # FFF;
Margin: 0.5em;
}
X-product: shadow. product-name {
Display: block;
Text-align: center;
Text-decoration: none;
Color: # 08C;
Border-top: 1px solid # EEE;
Font-weight: bold;
Padding: 0.75em 0;
}
To display the product, add the <x-product> element to the HTML template. Use the data-name, data-img, and data-url attributes to specify product-related data. When a page is loaded, custom elements call them through createCallback.
<X-product data-name = "Ruby" data-img = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url = "http://example.com/1"> </x-product>
<X-product data-name = "JavaScript" data-img = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url = "http://example.com/2"> </x-product>
<X-product data-name = "Python" data-img = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url = "http://example.com/3"> </x-product>
Now you have used Shadow DOM to customize an element to display a series of products.
All instance code
HTML
<X-product data-name = "Ruby" data-img = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url = "http://example.com/1"> </x-product> <x-product data- name = "JavaScript" data-img = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url = "http://example.com/2"> </x-product> <x-product data-name = "Python" data -img = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url = "http://example.com/3"> </x-product>
CSS
Body {background: # F7F7F7;} x-product {display: inline-block; float: left; margin: 0.5em; border-radius: 3px; background: # FFF; box-shadow: 0 1px 3px rgba (0,0, 0, 0.25); font-family: Helvetica, arial, sans-serif;-webkit-font-smoothing: antialiased ;} x-product: shadow. product-img {cursor: pointer; background: # FFF; margin: 0.5em;} x-product: shadow. product-name {display: block; text-align: center; text-decoration: none; color: # 08C; border-top: 1px solid # EEE; font-weight: bold; padding: 0.75em 0 ;}
JS
// Create a new object based on the HTMLElement prototypevar XProductProto = Object. create (HTMLElement. prototype); // Set up the element. XProductProto. createdCallback = function () {// Create a Shadow Root var shadow = this. createShadowRoot (); // Create a standard img element and set it's attributes. var img = document. createElement ('IMG '); img. alt = this. getAttribute ('data-name'); img. src = this. getAttribute ('data-img '); img. width = '000000'; img. height = '000000'; img. className = 'product-img '; // Add the image to the Shadow Root. shadow. appendChild (img); // Add an event listener to the image. img. addEventListener ('click', function (e) {window. location = this. getAttribute ('data-url') ;}); // Create a link to the product. var link = document. createElement ('A'); link. innerText = this. getAttribute ('data-name'); link. href = this. getAttribute ('data-url'); link. className = 'product-name'; // Add the link to the Shadow Root. shadow. appendChild (link) ;}; // Register the new element. var XProduct = document. registerElement ('x-product', {prototype: XProductProto });
Browser supports custom HTML elements
Chrome 33 + and Opera support custom elements. However, there is a powerful polyfill that allows other browsers, such as Polymer and X-tags.
You can use registerElement () to check whether the document object is supported by the browser:
If ('registerelement' in document ){
// Supported.
} Else {
// Not supported.
}
Summary
After learning this article, I believe you have learned how to use js to create custom HTML elements and how to build Web components using custom elements and Shadow DOM.