Приложения становятся все сложнее, и нам нужен способ разделять код на управляемые фрагменты. Веб-компоненты подойдут для создания компонентов, которые можно неоднократно использовать.
Веб-компоненты также изолированы от других участков кода, следовательно, их сложно изменить из других разделов и создать конфликтующий код.
В этой статье мы рассмотрим разные части веб-компонентов и способы их создания.
Части веб-компонентов
Веб-компоненты состоят из 3 основных частей. Вместе они инкапсулируют функциональность, которую можно повторно использовать в любое время, не опасаясь конфликтов кода.
- Пользовательский элемент — набор JavaScript API, позволяющий задавать пользовательские элементы, которые можно использовать в пользовательском интерфейсе, и их поведение.
- Теневой DOM — набор JavaScript API для подключения инкапсулированного дерева теневого DOM элемента. Он отображается отдельно от основного DOM документа, что сохраняет приватность функций элемента, следовательно, он может выполняться без конфликтов с другими частями документа.
- HTML шаблоны— элементы template или slot позволяют нам писать шаблоны разметки, которые не отображаются на странице. Их можно многократно использовать как основу структуры пользовательских элементов.
Создание веб-компонентов
Чтобы создать веб-компонент, нужно сделать следующее:
- Создать класс или функцию, чтобы определить функциональность веб-компонента.
- Зарегистрировать новый пользовательский элемент, используя метод CustomElementRegistry.define(), передающий имя элемента, который нужно определить, класс или функцию с заданной функциональностью, и, если необходимо, наследование элемента.
- Прикрепить теневой DOM к пользовательскому элементу, используя метод Element.attachSHadow(). Добавить дочерние элементы, слушатели событий и т.д. в теневой DOM, используя методы обычного DOM.
- Задать шаблоны HTML, используя тэги template и slot. Используем стандартные методы DOM для клонирования шаблона и подключения его к нашему теневому DOM.
- Использовать пользовательский элемент на странице как и любой другой обычный элемент HTML.
Базовые примеры
CustomElementRegistry хранит список определенных пользовательских элементов. Этот объект позволяет регистрировать новые пользовательские элементы на странице и возвращать информацию о зарегистрированных пользовательских элементах и т.д.
Для регистрации нового пользовательского элемента на странице используется метод CustomElementRegistry.define(). Он принимает следующие аргументы:
- Строчку, отображающую имя элемента (слова нельзя разделять пробелами, только дефисом).
- Объект класса, определяющий поведение элемента.
- Дополнительный аргумент, содержащий свойство extends, определяющее встроенный элемент, которому наследует новый элемент (если таковой имеется).
Пользовательский элемент задается так:
class WordCount extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); const span = document.createElement('span'); span.textContent = this.getAttribute('text').split(' ').length; const style = document.createElement('style'); style.textContent = 'span { color: red }'; shadow.appendChild(style); shadow.appendChild(span); } } customElements.define('word-count', WordCount);
В коде выше мы подключили теневой DOM к документу, вызвав attachShadow . Режим mode ‘open’ означает, что теневой корень доступен из JavaScript вне корня. Режим также может быть ‘closed’ с противоположным поведением.
Затем мы создали элемент span, где задали текстовое содержимое для атрибута text length после разделения слов пробелами.
Далее создали элемент style и задали содержимое color: red.
Наконец, мы присоединили их к корню теневого DOM.
Заметьте, что в нашем классе мы расширяем HTMLElement. Это необходимо для определения пользовательского элемента.
Использовать новый элемент можно следующим образом:
<word-count text='Hello world.'></word-count>
Существуют 2 типа пользовательских элементов:
- Автономные пользовательские элементы — независимые, не наследуют от стандартных HTML элементов. Их можно создать, ссылаясь напрямую на имя. Например, написать <word-count> или document.createElement(«word-count»).
- Настраиваемые встроенные элементы— наследуют от базовых HTML элементов. Для создания подобных элементов расширяем один из встроенных HTML элементов, например, написав <p is=»word-count»> или document.createElement(«p», { is: «word-count» }).
Пользовательский элемент, созданный выше — автономный. Настраиваемый элемент создается так:
class WordCount extends HTMLParagraphElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); const span = document.createElement('span'); span.textContent = this.getAttribute('text').split(' ').length; const style = document.createElement('style'); style.textContent = 'span { color: red }'; shadow.appendChild(style); shadow.appendChild(span); } } customElements.define('word-count', WordCount, { extends: 'p' });
Чтобы поместить его на страницу, пишем:
<p is='word-count' text='Hello world.'></p>
Как видите, автономные и настраиваемые элементы не сильно отличаются друг от друга. Единственное отличие — мы расширяем HTMLParagraphElement, а не HTMLElement .
Затем используем атрибут is для ссылки на пользовательский элемент вместо использования имени элемента в настраиваемом встроенном элементе.
Внутренние или внешние стили
Мы также можем ссылаться на внешние стили вместо использования внутренних, как сделано выше. Например, напишем:
const linkElem = document.createElement('link'); linkElem.setAttribute('rel', 'stylesheet'); linkElem.setAttribute('href', 'style.css'); shadow.appendChild(linkElem);
Мы ссылаемся на стили из style.css. Элемент link создается так же, как в HTML и нормальном DOM.
Создавать веб-компоненты просто. Нужно задать класс или функцию для определения функциональности и затем поместить их в реестр пользовательских элементов, используя метод customElements.define.
Мы можем расширить существующие элементы, такие как p, или создать новые с нуля. Также мы можем добавлять внутренние стили или ссылаться на внешние, создавая элемент link и ссылаясь на внешние файлы.
Специально для сайта ITWORLD.UZ. Новость взята с сайта NOP::Nuances of programming