DOM is continuously evolving. Some browsers adapt to it faster than others. This means that it's not always easy to make use of the latest innovations. Each time, developers need to think about which browsers are most frequently used by people who use their projects.
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 find yourself needing to support very old browsers that can barely do anything. This is often the case for government organizations.
For example, there is a method called matches()
that searches for elements by CSS selectors. It's supported by Internet Explorer, 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. This is done using polyfills.
The general principle of operation for these libraries is as follows:
The library with polyfills must be loaded before executing any other code. Only then will the rest of the code be able to count on the presence of the necessary properties.
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.
There's a much more complex option that involves adding the ParentNode.lastElementChild
. Here you directly have to program the logic for searching for the desired element.
// Note that the property is added in a special way,
// which allows you to make the property dynamic and lazy.
// I.e., its value will be calculated 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 straight away. The amount of code is beyond decency. Ensuring it works in the same way in all browsers (and all their versions) is not an easy task.
To find out the support for certain features in different browsers, there's an excellent resource https://caniuse.com/. And the easiest way to add polyfills to your website is to use the polyfill.io project. In addition to this project, GitHub has a huge number of ready-made polyfills for any parts of the DOM. They're scattered across different repositories belonging different people, so if you need to add a polyfill to something, you'll first have to spend time searching for the right library.
Sometimes, you just need to check for a certain feature, and depending on the result, execute different code. 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 has flash
} else {
// the browser does not have flash
}
});
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 much that it's difficult to work without them. Therefore, almost no modern project can do without the core-js library. This library covers almost all the features of modern JavaScript.
It's installed as a project dependency and is connected once at the topmost level of the application and does all the work itself, without needing to build the application using webpack.
import 'core-js/stable';
// other dependencies
Next in the course will be an exercise where in index.js you will see the connection of this library.
The Hexlet support team or other students will answer you.
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.
Programming courses for beginners and experienced developers. Start training for free
Our graduates work in companies:
From a novice to a developer. Get a job or your money back!
Sign up or sign in
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.