Skip to content

Instantly share code, notes, and snippets.

@warpech
Last active December 3, 2021 16:51
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save warpech/9431953 to your computer and use it in GitHub Desktop.
Save warpech/9431953 to your computer and use it in GitHub Desktop.
Web Components from the perspective of a jQuery developer

Web Components as successor to jQuery

This article is a homage to jQuery - a library that once was a great boost for the productiveness of thousands of web developers around the world. In the upcoming times, the benefit of using it will drop as web developers start to switch to the web standards, including Web Components.

Status quo

As of early 2014, current state of interactive web development heavily relies on established web standards - HTML, CSS and JavaScript, all of which have been subject to consistent iterative improvement during the last few years, with the support of all major web browser vendors.

As a report shows, 57.8% of all websites use JavaScript, of which stunning 93.2% use the jQuery library to enhance the development (source). There is a long tail of other libraries and micro frameworks that are being used instead, or in compliment to jQuery, but none of them has gotten close to the popularity of the jQuery.

jQuery has become the library of choice for the past 7 years by providing 3 major advantages:

  1. Levels the differences between major web browsers - now replaced with consistent JavaScript and CSS implementations
  2. A simple, easy to learn API - now replaced with JavaScript and CSS additions
  3. Extensive plugin ecosystem - facing a chance to be replaced with Web Components

Levels the differences between web browsers

In the times when Internet Explorer 6 ruled 90% of the users' desktops, the web developers were in a desperate need of maintaining code that runs both in Internet Explorer and web standards compliant browsers, such as Mozilla Firefox, Opera and early versions of Google Chrome.

jQuery since day one aimed at providing a consistent API that behaved the same way in all the browsers, handling each browser's quirks internally. This was a huge relief for the developer, who no longer needed to care about implementation details of a particular browser. It lead to a significant reduction of testing and bug fixing.

Since the release of IE10, all the major browsers support the web standards to the extent that lets them pass the Acid1, Acid2, Acid3 compliance tests.

What once was a great a major selling point of jQuery has become no longer significant, hence jQuery 2.0, released April 2013 dropped support for IE6-8 resulting in 15% file size reductiong and addmitedly loosing one if it's original purposes.

A Simple, easy to learn API

jQuery introduced a much simplified syntax over the regular JavaScript. With its short, multifunctional methods and the chainable flow of execution, it was possible to replace dozens of lines of JavaScript with just a single line of jQuery.

jQuery's expressive syntax has given inspiration to many APIs that are currently part of the standard JavaScript and CSS, being now natively implemented in browsers.

Other websites cover this in higher detail, but I will name just a few mostly used jQuery methods that now have a native implementation in browsers:

  • jQuery's $ function that finds elements in DOM using CSS selectors is being replaced with standard querySelector, querySelectorAll
  • jQuery's addClass, removeClass methods is being replaced with standard classList
  • jQuery's, each filter, map methods for array traversing are being replaced with standard forEach filter, map
  • jQuery's animate method mostly used to move the elements on screen is being replaced with more powerful and efficient CSS transitions

Using the native implementation of the above features means better performance and interoperability, so it is recommended over jQuery where possible.

Extensive plugin ecosystem

One can't argue that jQuery provides currently unbeatable collection of plugins that implement behavior and UI elements used in websites and web applications. The official jQuery Plugin Registry holds more than 2000 plugins, which is likely not even 10% of all jQuery plugins circulating around other places on the web.

A jQuery plugin can be inserted to any website given that:

  • the web developer loads the jQuery and the plugin file in the HTML <head>
  • all plugins on a page need to use the same version of jQuery, otherwise it gets very tedious (though not impossible) to integrate them
  • the web developer adds some JavaScript to the page in order to enable the plugin. Usually they also need to add some id or a classnames to the elements where the plugin needs to be executed. If the webpage content is dynamic (something is created on screen after the page is loaded), the web developer needs to make sure that the plugin will also work on the dynamically created elements, which is not always straightforward and requires learning how the plugin works

Web Components share some of the above steps but in a simpler way:

  • the web developer loads the shim library (such as Polymer) and the HTML import in the HTML <head>
  • all Web Components on a page need to use the same version of the shim library. Given that the shim library implements agreed standards, it is more likely that upgrading the library will not break the existing code
  • the web developer adds a Custom Element to the page, most likely without a single line of JavaScript. This is very important for the novice developers. Also, because of being first-class DOM members, Custom Elements may be dynamically added to the website and will work as fine as if they were included during the page load

Web Components

Set of new technologies

Web Components is an umbrella term for the set of upcoming standards for web development (see the W3C Web Components page). Each on its own, they are a useful contribution to the current toolset of a web developer. But together they form a completely new paradigm of how web applications are created.

Web Components consist of 4 standards proposals:

  1. Templates
  2. Shadow DOM
  3. Custom Elements
  4. Imports

Templates

Templates define reusable parts of DOM. Whatever is in a Template, is not executed until the Template content is actually appended to the DOM. That means <img> sources are not downloaded, scripts are not executed until neccessary - saving on bandwidth and processing. Also, whatever is in a Template is hidden from querySelector so the scripts on your page won't accidentaly manipulate the original contents of a Template.

Using Templates is as easy as:

<template id="tpl">
Hello world!
</template>

<script>
var tpl = document.querySelector('#tpl');
tpl.content.querySelector('.name').textContent = "World";
var clone = document.importNode(tpl.content, true);
document.body.appendChild(clone);
</script>

Produces:

Live code on jsFiddle (use Chrome Canary with Web Platform features enabled)

More info on HTML's New Template Tag by Eric Bidelman.

Shadow DOM

Shadow DOM provides markup and style encapsulation.

This is a feature that was used by browser vendors for the long time. Let's think of a <video> tag. It consists of controls like the play button, progress bar and the volume controls. Each of those controls is implemented as a <div> inside of the <video> tag that is actually not accessible for the the scripts on the page but is rendered on users screen.

Shadow DOM is a tool that let's the web developer create his own hidden encapsulated markup and styles in the same way in which <video> controls are made.

The simplest example of using Shadow DOM is:

<button>Push me</button>

<script>
var host = document.querySelector('button');
var root = host.createShadowRoot();
root.innerHTML = 'Do not <content></content>!';
</script>

Produces:

Live code on jsFiddle

More info on Shadow DOM 101 by Dominic Cooney.

Custom Elements

Custom Elements = Templates + Shadow DOM.

With the combined power of Templates and Shadow DOM you are now in power to create first-class HTML elements that extend the browser.

What is great about Custom Elements, as opposed to, say jQuery plugins, is that being first-class DOM members, the Custom Elements can react to the DOM lifecycle events. That enables them to have a certain behavior when they are added to DOM, their attributes change or they are removed from DOM.

A simple Custom Element can look like that:

<template id="myGravatarTemplate">
    <img>
</template>
<my-gravatar email="albert.einstein.starcounter@gmail.com"></my-gravatar>

<script>
function updateImg(img, email) {
    img.setAttribute("src", "//www.gravatar.com/avatar/" + SparkMD5.hash(email));
}

var MyGravatarElementPrototype = Object.create(HTMLElement.prototype);
MyGravatarElementPrototype.attributeChangedCallback = function (attributeName, oldVal, newVal) {
    if (attributeName == "email") {
        updateImg(this.shadowRoot.querySelector('img'), newVal);
    }
};
MyGravatarElementPrototype.createdCallback = function () {
    var t = document.querySelector('#myGravatarTemplate');
    var clone = document.importNode(t.content, true);
    updateImg(clone.querySelector('img'), this.getAttribute("email") || "");
    this.createShadowRoot().appendChild(clone);
};

var MyGravatarElement = document.registerElement('my-gravatar', {
    prototype: MyGravatarElementPrototype
});
</script>

Produces:

(Live code on jsFiddle)[http://jsfiddle.net/7y6kp/7/]

More info on Custom Elements - defining new elements in HTML by Eric Bidelman.

Imports

Imports load external resources, such as Templates or Custom Elements.

Assuming the above Custom Element definition is contained in a file my-gravatar.html, the following code will bring the avatar image on screen:

<link rel="import" href="my-gravatar.html">
<my-gravatar email="albert.einstein.starcounter@gmail.com"></my-gravatar>

Imported HTML files can contain templates, stylesheets and scripts. They get executed when the import is loaded.

Further reading

These are the fundamentals of Web Components. So far, I have only presented usage of native APIs already implemented in Google Chrome Canary. With Polymer, the same code will work in any modern browser and may be simplified with some powerful syntactic sugar. I will cover that in the following blog posts.

@julianjpoole
Copy link

"Assuming the above Custom Element definition is contained in a file my-gravatar.html" Have you actually tried this because it doesn't work. It should i know but it comes back with the error:

"Uncaught TypeError: Cannot read property 'content' of null"

Which fundamentally destroys one of the main corner stones as to why you would want to use web components... html imports.

@hyyan
Copy link

hyyan commented Jul 3, 2016

Great Article , thanks a lot

@cursomicroforum2015
Copy link

cursomicroforum2015 commented Feb 9, 2018

Funny that as of February 2018 most of those JFiddle examples only work on Chrome. It seems jQuery will stay for a while...

@TheKiesel
Copy link

Yeah... that doesn't work. Only in Chrome.

@anton5rov
Copy link

anton5rov commented Jun 29, 2019

Shouldn't it be:
<template id="tpl">
Hello <span class="name"></span>!
</template>

<span class="name"></span> must replace the "World" in the first example, right?

@athena123
Copy link

It is wrong to say Custom Elements = Templates + Shadow DOM!!! Custom Elements is independent of Templates and shadow DOM. The three together make up the pillars of Web Components

@warpech
Copy link
Author

warpech commented Dec 11, 2019

It is wrong to say Custom Elements = Templates + Shadow DOM!!! Custom Elements is independent of Templates and shadow DOM. The three together make up the pillars of Web Components

@antena123 thanks for reading. You are completely right. In my defense, the above text is 5 years old. The best would be to delete it. I will keep it though, so that it may inspire someone else to write a better piece :)

@athena123
Copy link

@warpech thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment