So, i developed angular application about a month ago, and i wondered why in angular app the element name is unique and different with HTML element, and the element will still unique even in build release.
Today when i read Javascript Notes For Professionals (it is a book writen by GoalKicker group, you can download it here), i saw something that took my interest, "Chapter 51: Custom Elements".
That chapter explains about creating custom element with document.registerElement()
which is already deprecated. So, i searched for another method, and here is what i found.
1. What We Will Build
A simple timer element named app-timer
with red background, of course we will build it as custom element.
2. Code
We will use customElements.define()
method in this post, because it's the recommended way to define custom element in modern javascript.
Create an index.html file and paste these codes:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Element Example</title>
</head>
<body>
<script>
class Timer extends HTMLElement {
constructor() {
super()
}
}
customElements.define('app-timer', Timer)
</script>
<app-timer/>
</body>
</html>
Okay let's explain it one by one
First, we create Timer
class that extends HTMLElement
class, then we define the constructor method with nothing inside it except executing super
method.
Then, we call define method from customElements
class with "app-timer" and Timer
class as its argument, "app-timer" is element tag name (like body, footer, head) and Timer
class is element handler class.
Please note that element tag name should include a hypen(-), "x-footer" and "my-element" is a valid element tag name while "myblock" and "header_block" is not.
Then let's run this html file in browser.
Yep, there's nothing here, because we haven't add anything into the custom element, it would be scary if there is something shown in the page.
Add timer functionality to constructor method, so it will looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Element Example</title>
</head>
<body>
<script>
class Timer extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({mode:"open"})
shadow.innerHTML = "1"
setInterval(()=>{
shadow.innerHTML = parseInt(shadow.innerHTML) + 1
}, 1000)
}
}
customElements.define('app-timer', Timer)
</script>
<app-timer/>
</body>
</html>
And again, let's explain things line by line
const shadow = this.attachShadow({mode:"open"})
we define shadow constant with value returned from attachShadow()
method. attachShadow()
used to get our custom element DOM property, we can't access the property directly, it will throws error.
shadow.innerHTML = "1"
You must be familiar with this code, yep, we add text to element's innerHTML.
setInterval(()=>{
shadow.innerHTML = parseInt(shadow.innerHTML) + 1
}, 1000)
Increase value of custom element's innerHTML by 1 every second.
Ok try to run it and you won't see blank page anymore.
And that's it, we have added timer functionality to custom element.
Is it enough? No
Don't forget about the red background part, we must add style to this custom element. We will place the code that change element style in connectedCallback()
method. This method executed after the Element is rendered, so we won't face DOM issues.
class Timer extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({mode:"open"})
shadow.innerHTML = "1"
setInterval(()=>{
shadow.innerHTML = parseInt(shadow.innerHTML) + 1
}, 1000)
}
connectedCallback(){
this.style.backgroundColor = "red"
this.style.padding = "10px"
}
}
customElements.define('app-timer', Timer)
You can do anything in connectedCallback()
method, manipulating DOM, rendering, there is no restriction. Ok, time to test our app again.
And as you can see, the app-timer
element background color turns into red, i even added padding for beautifier. You can try it by your own on the codesandbox below.
References
- Javascript Notes for Professionals
- Google Developers Custom Element Docs
- Some StackOverflow Thread
Thanks to Tranmautritam in Pexels for their beautiful picture (the picture i used in banner).
Top comments (0)