Building a Pager Web Component - Part 2: Template & Shadow DOM
In the last post, we started building a pager web component. In this post, we will continue with this, making use of a template and the shadow DOM.
Moving the markup to a template
At the moment, the markup for our component is defined in createdCallback()
. Let’s now define this in a template with some styling:
<template>
<style>
.x-pager-link {
margin-right: 6px;
text-decoration: none;
}
a.x-pager-link:hover {
text-decoration: underline;
}
.x-pager-text {
margin-left: 20px;
}
</style>
<div>
<a href="#" title="Go to the first page" class="x-pager-link">first</a>
<a href="#" title="Go to the previous page" class="x-pager-link"
>previous</a
>
<a href="#" title="Go to the next page" class="x-pager-link">next</a>
<a href="#" title="Go to the last page" class="x-pager-link">last</a>
<span class="x-pager-text">page x of y</span>
</div>
</template>
We now need to reference this template in createdCallback()
- we do this using:
var template = document.querySelector("template"),
clone = document.importNode(template.content, true);
Adding the markup to the shadow DOM
In order to use the markup that we have extracted from the template, we will use the shadow DOM. First we need to get a reference to the shadow root using this.createShadowRoot()
. Then we add the template’s content to the shadow root using root.appendChild()
.
The full listing for our component is now:
<!DOCTYPE html>
<html>
<head> </head>
<body>
<h1>my app</h1>
<x-pager page="1" page-count="5"></x-pager>
<template>
<style>
.x-pager-link {
margin-right: 6px;
text-decoration: none;
}
a.x-pager-link:hover {
text-decoration: underline;
}
.x-pager-text {
margin-left: 20px;
}
</style>
<div>
<a href="#" title="Go to the first page" class="x-pager-link">first</a>
<a href="#" title="Go to the previous page" class="x-pager-link"
>previous</a
>
<a href="#" title="Go to the next page" class="x-pager-link">next</a>
<a href="#" title="Go to the last page" class="x-pager-link">last</a>
<span class="x-pager-text">page x of y</span>
</div>
</template>
<script>
(function() {
var Proto = Object.create(HTMLElement.prototype),
root;
Proto.createdCallback = function() {
var template = document.querySelector("template"),
clone = document.importNode(template.content, true);
root = this.createShadowRoot();
root.appendChild(clone);
};
document.registerElement("x-pager", { prototype: Proto });
})();
</script>
</body>
</html>
Our component now looks like below.
Next time we’ll separate our component into it’s own html file.