Lessons: 2Length: 11 minutes

Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

1.2 Use Web Components in Vanilla JavaScript

In this lesson, we’ll first take a look at the template for our web component—this template contains its underlying markup and styling. Next, we’ll use the Shadow DOM to shield this markup from the DOM of the page it’s used on, encapsulating the component’s HTML elements and CSS. Then, we’ll create a custom tag name to aid reuse. Finally, we’ll look at how to import the component into a new page in a separate HTML file.

Code Snippet

To create a web component, we first get the DOM element corresponding to its template.

var template = document.currentScript.ownerDocument.querySelector('template');

Next, we can add a callback that gets invoked whenever the custom element is rendered on a page. Inside the callback, we can create a shadow root for the custom element and import the template.

var progressIndicatorProto = Object.create(HTMLElement.prototype);
progressIndicatorProto.createdCallback = function () {
  var root = this.createShadowRoot();
  root.appendChild(document.importNode(template.content, true));
}

Finally, we register this callback with the desired element name.

var progressIndicator = document.registerElement ('progress-indicator', {
  prototype: progressIndicatorProto
});

All we need to do to import the component into another page is use a <link rel="import" href="..."/> element with an href that points to the web component template file.

Related Links

1.Use Web Components in Vanilla JavaScript
2 lessons, 10:51

1.1
Introduction
00:47

1.2
Use Web Components in Vanilla JavaScript
10:04


1.2 Use Web Components in Vanilla JavaScript

[SOUND] Hi folks, in this lesson we're going to use the four technologies of web components to build a simple web component. The component we'll be building is a steps indicator that might be used on each page of a process like a checkout process, for example. So let's make a stop. We just need to clone the wrapper from GitHub. In the repository is a file called progress-indicator.html. Let's open that up and take a look. The market for a web component is inside the HTML five template element. We've got a style element in here that contains the basic CSS styling for the component, we've also got the markup the progress indicator that will be converting into a web component. The template is one of the core parts of a web component, and we'll be modifying it later on. So if we run this page in a browser now, none of the markup inside the template element will be rendered, because a template is considered inherent and we need to activate it. We want to render the template into an element on the page. So let's add a simple &gt;&gt; First of all What we want to do now, is use the shadow Dom to render the template, the shadow Dom is another core aspect to Web Components. And is what gives us the encapsulation which make web components so awesome. In our JavaScript. Then we'll need to select the templates and container and create a shadow route inside the container. We use QuerySelector to select the template and the container. We then use the createShadowRoot method on the container to create a shadow roots which we need to inject our template into the shadow doom. An element containing a shadow route is known as a shadow post, hence the variable name here, host. Now let's insert the templates. We use the importNode method of the document and specify what to import as the first argument and whether to do a deep copy as the second argument. We can get the elements in the template using the content property of the selected template. We should now be able to run the paging chrome and see the first iteration of the progress indicator great next. We don't want to have a hard coded number of steps in the template the idea is that the user of the component should be able to policy in as many steps as there are In the process that the indicator is full. To fix this, let's copy the ally elements into the container and then add a content element to the template. The content element allows us to specify the element that will be supplied by the container using the select attribute. We've just copied the LOA elements into the progress container, and these elements will be projected into the shadow don't we create. The content element is actually deprecated right now, but at this point there was no clear alternative to use and it may even come back at some point in the future. The styling for the component is now broken because it targets Li elements in the template and there now aren't any. We need to use the content pseudo element. In the CSS, we just find a replace Li with content Li and that fixes the styling. Instead of using a generic div element as the container, we can use another core aspect of web components, custom elements. Let's implement a progress hyphen indicates a custom elements. We'll need to make a few changes to the script for this part. First of all, we can ditch the host variable as we won't be needing that anymore to create a custom element we need to create a new prototype that inherits from HTML elements. We can add this off to the initial template variable we use object or create to create new objects and set its prototype to the prototype of HTML element. When an instance of our custom element is rendered a call back will be invoked and we can use this to do any set up for the element. We can use this callback to create the shadow roots and inject the templates. We just assign a function to the created call back property of the new object we created. We can then move the root variable and bit where we inject the template into this function. We also need to update hostile create shadow routes to this create shadow routes. Next, we need to register the custom element. We use the registerElement method of the document. The first argument is the tag name of the custom element which must contain a hyphen. The second argument is an object which allows us to specify the prototype for the custom element which we set to the object we created a moment ago. We can now update the container to be a progress-indicator element. We should still be able to run the page and see our fully fledged web component in action. There's one more core aspect of web-components that we haven't looked at yet, and it's the most contentious part of the spec, html imports. Ideally, we want to be able to package up our web-component and make it easily distributable, so that other developers can use it in their own pages without any copy pasting of stylesheets, scripts, or markup. We need to make a couple of changes to what we've done so far to make this work. First of all. Let's create a new HTML page in the root of our project code index.html. In the head of this page we just need to import our component. We do this using a link element, just like how we import stow sheets. In this case, the rel is set to the type imports and the hatred points to the file we want to import back in the progress hyphen indicator file. We can strip out all of the hate mail boilerplate, and move the custom Progress Indicator element. And the steps into the index page. Lastly, we just need to make a minor modification to the script in the progress hyphen indicates a page in the first line of the script, where we select the template using document doc weary selector We need to change this line to document.currentScript.ownerdocument. The reason for this change is because when the progress hyphen indicates a page is imported into the host document, the styles and script will be applied immediately. So even from within the web component, documents will refer to the document in the host page and the template doesn't exist there. So it will go through an error. Changing this line allows us to select the template in the web component from the host document. If we run the new index page in our browser now, we should find that it works exactly the same as before. We can easily change the class names on the steps elements to set the completed and active steps and we can change these programatically and the correct styles will be applied. Perfect. So today we've looked at the four key aspects of web components, Templates, the Shadow DOM, Custom Elements, and HTML Imports. And we've seen how to use these aspects together to create a simple reusable web component. At the moment, and by moment I mean early 2016, this demo only works in Chrome and Opera. It doesn't work in Firefox, even with the Web Components preference enabled, and it doesn't work at all in Edge. The only blocker to using web components today without polyfills is the browser vendors haven't agreed on the spec. At some point in the future, there may or may not be an alternative to how HTML imports work currently. And there may be new elements that we need to use in templates. Because the content element that we use today is actually deprecated. Once these hurdles have been overcome however, we should see an explosion of web components used with Vanilla JavaScript. Thanks for watching.

Back to the top