Register to get access to free programming courses with interactive exercises

Polyfills JS: DOM API

DOM is continuously evolving. Some browsers adapt to it faster than others, so using the latest innovations is not always easy. Each time developers should think about which browsers future customers most frequently use.

Developers usually use analytics to find out which browsers are more popular. An example is Google Analytics, which collects data in real-time from everyone who visits the site.

In some particularly complex situations, you may need to support old browsers that can barely do anything. It is often the case for government organizations.

For example, let's observe a method called matches() that searches for elements by CSS selectors. Internet Explorer supports it, but only as of version 9. If your project claims to be compatible with IE8, then there'll be an error if you call this method:

const div = document.querySelector('div');
div.matches('.someClass'); // Uncaught TypeError: matches is not a function

Fortunately, the nature of JavaScript means you can partially compensate for the shortcomings of older browsers. Thanks to prototypes, developers still have an opportunity to add missing functionality directly to the DOM implementation. We can do it using polyfills.

The general principle of operation for these libraries is as follows:

  1. Check if the desired method or property is available
  2. If it isn't there, then add it

We should load the library with polyfills before executing any other code. Only then will the rest of the code be able to count on the presence of the necessary properties. f the code be able to count on the presence of the necessary properties.

Adding a method

Below is an example of a polyfill for the node.matches() method. This polyfill works for all popular browsers and uses their specific features. You can see by the names of the properties:

(function(constructor) {
  const p = constructor.prototype;
  if (!p.matches) {
    p.matches = p.matchesSelector ||
    p.mozMatchesSelector ||
    p.msMatchesSelector ||
    p.oMatchesSelector ||
    p.webkitMatchesSelector;
  };
})(window.Element);

After executing this code, you can use the element.matches() method without worrying about it not existing in older browsers.

Adding a property

Let's discuss a more complex option that involves adding the ParentNode.lastElementChild. In this case, you have to program the logic for searching for the desired element:

// Note that we added the property in an unusual way
// It allows you to make the property dynamic and lazy.
// So, the program calculates its value only at the time of the request
if (!('lastElementChild' in document.documentElement)) {
  Object.defineProperty(Element.prototype, 'lastElementChild', {
    get: function() {
      for (let nodes = this.children, n, i = nodes.length - 1; i >= 0; --i) {
        if (n = nodes[i], 1 === n.nodeType) {
          return n;
        }
      }
      return null;
    }
  });
}

The examples above are incomplete. If you look at the sources of the corresponding libraries, you'll want to close them away. The amount of code is beyond decency. Ensuring it works the same way in all browsers and all their versions is challenging.

There's an excellent resource CanIUse, which helps to learn about the support for specific features in different browsers:

Can I Use

And the easiest way to add polyfills to your website is to use the polyfill.io project. In addition to this project, GitHub has many ready-made polyfills for all parts of the DOM. They scatter across repositories belonging to different people, so if you need to add a polyfill to something, you'll first have to spend time searching for the library.

Sometimes, you check for a feature and decide what code to execute. In this kind of situation, the modernizr library will help:

// Checks to see if flash is there
Modernizr.on('flash', (result) => {
  if (result) {
   // The browser supports flash
  } else {
    // The browser does not support flash
  }
});

JavaScript Core

But there aren't just polyfills for the DOM. JavaScript itself is also continuously developing, especially in recent years. Many features of modern JavaScript simplify development, so it's hard to work without them. Therefore, almost no project can do without the core-js library. This library covers nearly all the features of modern JavaScript.

It installs as a project dependency, connected once at the topmost level of the application. So, it does all the work without needing to build the application using webpack:

import 'core-js/stable';
// Other dependencies

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

Bookmate
Health Samurai
Dualboot
ABBYY
Suggested learning programs
profession
Development of front-end components for web applications
10 months
from scratch
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.