Что такое полифил javascript

Полифиллы — JS: DOM API

DOM непрерывно развивается. Какие-то браузеры его адаптируют быстрее, какие-то медленнее. Все это не позволяет легко и непринужденно пользоваться последними новинками. Разработчикам каждый раз нужно думать о том, какие браузеры распространены у пользователей их проектов.

Информацию о том какие браузеры актуальны, обычно, узнают из аналитики, например google analytics, которая в режиме реального времени собирает её со всех, кто заходит на сайт.

В некоторых, особо сложных ситуациях, приходится поддерживать совсем старые браузеры, которые практически ничего не могут. Такое нередко встречается в государственных организациях.

Например, есть метод matches() , который ищет элементы по CSS-селекторам. Он поддерживается Internet Explorer, но только с 9й версии. Если в вашем проекте заявлена совместимость с 8й, то на вызов этого метода будет получена ошибка.

К счастью, природа JavaScript позволяет частично компенсировать недостатки старых браузеров. Благодаря прототипам у разработчиков есть возможность добавить недостающую функциональность прямо в реализацию DOM. Делается это с помощью полифиллов.

Общий принцип работы этих библиотек следующий:

  1. Проверяем наличие нужного метода или свойства.
  2. Если их нет, то добавляем.

Важно чтобы библиотека с полифиллами грузилась до выполнения любого другого кода. Только в этом случае остальной код может рассчитывать на наличие нужных свойств.

Добавление метода

Ниже пример полифилла для метода node.matches() . Этот полифилл работает для всех популярных браузеров и задействует их специфику (видно по именам свойств).

После выполнения этого кода, можно использовать метод element.matches() , не боясь его отсутствия в старых браузерах.

Добавление свойства

Значительно более сложный вариант – добавление свойства ParentNode.lastElementChild . Здесь прямо приходится программировать логику поиска нужного элемента.

Примеры выше не являются полными. Если посмотреть исходники соответствующих библиотек, то хочется их быстрее закрыть. Количество кода иногда зашкаливает до неприличия. Обеспечение универсальной работы во всех браузерах (и всех их версиях) непростая задача.

Чтобы узнать поддержку определенных фич в разных браузерах, можно воспользоваться прекрасным ресурсом https://caniuse.com/. А самый простой способ добавить полифиллы на свой сайт — это воспользоваться проектом polyfill.io. Кроме этого проекта, на гитхабе огромное количество готовых полифиллов для любых частей DOM. Они разбросаны по разным репозиториям разных людей, поэтому если вам понадобится что-то полифиллить, то сначала придется потратить время на поиск нужной библиотеки.

Ядро JavaScript

Но полифиллы бывают не только для DOM. Сам JavaScript тоже непрерывно развивается, особенно последние годы. Многие фичи современного JavaScript настолько упрощают разработку, что без них уже сложно. Поэтому практически ни один современный проект не обходится без библиотеки core-js. Эта библиотека закрывает почти все возможности современного JavaScript.

Она устанавливается, как зависимость проекта и один раз подключается на самом верхнем уровне приложения и делает сама всю работу, без необходимости сборки приложения вебпаком.

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

Полифил

Полифил — это фрагмент кода (в сети — обычно JavaScript), который позволяет использовать современную функциональность в более старых браузерах, которые не поддерживают ее по умолчанию.

Например, полифил можно использовать, чтобы эмулировать функциональность text-shadow в IE7 с помощью нативных фильтров браузера, или рем и медиавыражения, динамически меняя стилизацию в нужных случаях с помощью JavaScript, или что-либо еще, что вам потребуется.

Из-за меньшей производительности и ограниченной функциональности нельзя использовать исключительно полифилы. Нативная реализация API быстрее и с ней можно сделать больше, чем с помощью полифила. Например, полифил Object.create может эмулировать только то, что доступно для ненативной реализации Object.create.

В других случаях полифилы нужны, чтобы разрешить ситуации, когда браузеры реализуют одни и те же возможности разными способами. Тогда полифил использует нестандартные возможности конкретного браузера, чтобы в результате определенная функциональность была совместима с действующими стандартами JavaScript. Хотя такое применение полифилов и редкость сейчас, во времена IE6 и Netscape, когда каждый браузер реализовывал JavaScript очень по-разному, оно было широко распространено. Первая версия JQuery была ранним примером полифила. Она представляла собой компиляцию из обходных путей, специфических для определенных браузеров, которая предоставляла JavaScript-разработчикам единый API для всех браузеров. В то время одной из наибольших проблем было заставить сайт работать на всех устройствах: браузеры настолько существенно различались, что порой код приходилось писать совершенно по-разному и разрабатывать разные пользовательские интерфейсы, исходя из используемого пользователем браузера. Таким образом, у JavaScript-разработчиков был доступ только к очень лимитированному количеству JavaScript API, которые работали более или менее одинаково во всех браузерах. Сейчас использование полифилов для взаимодействия со специфичными для браузера реализациями возможностей менее распространено, так как современные браузеры в большинстве своем имеют большой набор стандартизированных API.

Современный DOM: полифилы

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

В старых IE, особенно в IE8 и ниже, ряд стандартных DOM-свойств не поддерживаются или поддерживаются плохо.

Если говорить о современных браузерах, то они тоже не все идут «в ногу», всегда какие-то современные возможности реализуются сначала в одном, потом в другом.

Но это не значит, что нужно ориентироваться на самый старый браузер из поддерживаемых!

Для того, чтобы не думать об устаревших браузерах, а писать современный код, который при этом работает везде, используют полифилы.

Полифилы

«Полифил» (англ. polyfill) – это библиотека, которая добавляет в старые браузеры поддержку возможностей, которые в современных браузерах являются встроенными.

Один полифил мы уже видели, когда изучали собственно JavaScript – это библиотека ES5 shim. Если её подключить, то в IE8- начинают работать многие возможности ES5. Работает она через модификацию стандартных объектов и их прототипов. Это типично для полифилов.

В работе с DOM несовместимостей гораздо больше, как и способов их обхода.

Что делает полифил?

Для примера добавим в DOM поддержку свойства firstElementChild , если её нет. Здесь речь, конечно, об IE8, в других браузерах оно и так поддерживается, но пример типовой.

Вот код для такого полифила:

Если этот код запустить, то firstElementChild появится у всех элементов в IE8.

Общий вид этого полифила довольно типичен. Обычно полифил состоит из двух частей:

  1. Проверка, есть ли встроенная возможность.
  2. Эмуляция, если её нет.

Проверка встроенного свойства

Для проверки встроенной поддержки firstElementChild мы можем просто обратиться к document.documentElement.firstElementChild .

Если DOM-свойство firstElementChild поддерживается, то его значение не может быть undefined . Если детей нет – свойство равно null , но не undefined .

За счёт этого работает проверка в первой строке полифила.

Важная тонкость – элемент, который мы тестируем, должен по стандарту поддерживать такое свойство.

Попытаемся, к примеру, проверить «поддержку» свойства value . У input оно есть, у div такого свойства нет:

Если мы хотим проверить поддержку не свойства целиком, а некоторых его значений, то ситуация сложнее.

Например, нам интересно, поддерживает ли браузер <input type="range"> . То есть, понятно, что свойство type у input , в целом, поддерживается, а вот конкретный тип <input> ?

Для этого можно создать <input> с таким type и посмотреть, подействовал ли он.

  1. Первый input имеет type="radio" . Этот тип точно поддерживается, поэтому input.type имеет значение "radio" , как и указано.
  2. Второй input имеет type="no-such-type" . В качестве типа, для примера, специально указано заведомо неподдерживаемое значение. При этом input.type равен "text" , таково значение по умолчанию. Мы можем прочитать его и увидеть, что поддержки нет.

Эта проверка работает, так как хоть в HTML-атрибут type и можно присвоить любую строку, но DOM-свойство type по стандарту хранит реальный тип input’а .

Добавляем поддержку свойства

Если мы осуществили проверку и видим, что встроенной поддержки нет – полифил должен её добавить.

Для этого вспомним, что DOM элементы описываются соответствующими JS-классами.

  • <li> – HTMLLiElement
  • <a> – HTMLAnchorElement
  • <body> – HTMLBodyElement

Они наследуют, как мы видели ранее, от HTMLElement, который является общим родительским классом для HTML-элементов.

А HTMLElement , в свою очередь, наследует от Element, который является общим родителем не только для HTML, но и для других DOM-структур, например для XML и SVG.

Для добавления нужной возможности берётся правильный класс и модифицируется его prototype .

Например, можно добавить всем элементам в прототип функцию:

Сложнее – добавить свойство, но это тоже возможно, через Object.defineProperty :

В IE8 современные методы для работы со свойствами, такие как Object.defineProperty, Object.getOwnPropertyDescriptor и другие не поддерживаются для произвольных объектов, но отлично работают для DOM-элементов.

Чем полифилы и пользуются, «добавляя» в IE8 многие из современных методов DOM.

Какова поддержка свойства?

А нужен ли вообще полифил? Какие браузеры поддерживают интересное нам свойство или метод?

Зачастую такая информация есть в справочнике MDN, например для метода remove() : https://developer.mozilla.org/en-US/docs/Web/API/ChildNode.remove – табличка совместимости внизу.

Итого

Если вы поддерживаете устаревшие браузеры – и здесь речь идёт не только про старые IE, другие браузеры тоже обновляются не у всех мгновенно – не обязательно ограничивать себя в использовании современных возможностей.

Многие из них легко полифилятся добавлением на страницу соответствующих библиотек.

Для поиска полифила обычно достаточно ввести в поисковике "polyfill" , и нужное свойство либо метод. Как правило, полифилы идут в виде коллекций скриптов.

Полифилы хороши тем, что мы просто подключаем их и используем везде современный DOM/JS, а когда старые браузеры окончательно отомрут – просто выкинем полифил, без изменения кода.

Типичная схема работы полифила DOM-свойства или метода:

  • Создаётся элемент, который его, в теории, должен поддерживать.
  • Соответствующее свойство сравнивается с undefined .
  • Если его нет – модифицируется прототип, обычно это Element.prototype – в него дописываются новые геттеры и функции.

Другие полифилы сделать сложнее. Например, полифил, который хочет добавить в браузер поддержку элементов вида <input type="range"> , может найти все такие элементы на странице и обработать их, меняя внешний вид и работу через JavaScript. Это возможно. Но если уже существующему <input> поменять type на range – полифил не «подхватит» его автоматически.

Описанная ситуация нормальна. Не всегда полифил обеспечивает идеальную поддержку наравне с родными свойствами. Но если мы не собираемся так делать, то подобный полифил вполне подойдёт.

Один из лучших сервисов для полифилов: polyfill.io. Он даёт возможность вставлять на свою страницу скрипт с запросом к сервису, например:

При запросе сервис анализирует заголовки, понимает, какая версия какого браузера к нему обратилась и возвращает скрипт-полифил, добавляющий в браузер возможности, которых там нет. В параметре features можно указать, какие именно возможности нужны, в примере выше это функции стандарта ES6. Подробнее – см. примеры и список возможностей.

Также есть и другие коллекции, как правило, полифилы организованы в виде коллекции, из которой можно как выбрать отдельные свойства и функции, так и подключить всё вместе, пачкой.

    – ES5 вместе с DOM – ES5 вместе с DOM – ES5+ вместе с DOM

Более мелкие библиотеки, а также коллекции ссылок на них:

Конечно, можно собрать и свою библиотеку полифилов самостоятельно из различных коллекций, которые перечислены выше, а при необходимости и написать самому. В этой части учебника мы изучим ещё много методов работы с DOM, которые в этом помогут.

Добавить комментарий

Ваш адрес email не будет опубликован.