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:
- Check if the desired method or property is available
- 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:
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.