1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
---
title: Веб-компоненты
slug: Web/Web_Components
translation_of: Web/Web_Components
---
<p>{{DefaultAPISidebar("Веб-компоненты")}}</p>
<p>Веб-компоненты - это набор различных технологий, позволяющих создавать повторно используемые настраиваемые элементы с их функциональностью, инкапсулированной отдельно от остальной части вашего кода - и использовать их в ваших веб-приложениях.</p>
<h2 id="Понятия_и_использование">Понятия и использование</h2>
<p>Как разработчики, все мы знаем, что как можно больше повторного использования кода - хорошая идея. Традиционно это было не так просто для пользовательских структур разметки - подумайте о сложном HTML (и связанном с ним стиле и сценарии), которые вам иногда приходилось писать для визуализации пользовательских элементов управления UI, и о том, как их многократное использование может превратить вашу страницу в беспорядок если вы не будете осторожны.</p>
<p>Веб-компоненты направлены на решение таких проблем - они состоят из трех основных технологий, которые можно использовать вместе для создания универсальных настраиваемых элементов с инкапсулированной функциональностью, которые можно повторно использовать где угодно, не опасаясь коллизий кода.</p>
<ul>
<li><strong>Пользовательские элементы</strong>: набор API-интерфейсов JavaScript, позволяющих определять пользовательские элементы и их поведение, которые затем можно использовать по желанию в пользовательском интерфейсе.</li>
<li><strong>Shadow DOM</strong>: набор API-интерфейсов JavaScript для прикрепления инкапсулированного «теневого» дерева DOM к элементу, который отображается отдельно от DOM основного документа, и управления соответствующими функциями. Таким образом, вы можете сохранить функции элемента в секрете, поэтому для них можно создавать сценарии и стили, не опасаясь коллизий с другими частями документа.</li>
<li><strong>HTML templates</strong>: элементы {{HTMLElement("template")}} и {{HTMLElement("slot")}} позволяют создавать шаблоны разметки, которых не видно на отображаемой странице. Затем их можно многократно использовать в качестве основы структуры настраиваемого элемента.</li>
</ul>
<p>Базовый подход к реализации веб-компонента обычно выглядит примерно так:</p>
<ol>
<li>Создайте класс, в котором вы указываете функциональность своего веб-компонента, используя синтаксис классов ECMAScript 2015 (дополнительную информацию см. в разделе <a href="https://wiki.developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes">Классы</a>).</li>
<li>Зарегистрируйте свой новый настраиваемый элемент с помощью метода {{domxref("CustomElementRegistry.define()")}}, передав ему имя элемента, который будет определен, класс или функцию, в которых указана его функциональность, и, необязательно, от какого элемента он наследуется.</li>
<li>При необходимости прикрепите теневую DOM к настраиваемому элементу с помощью метода {{domxref("Element.attachShadow()")}}. Добавьте дочерние элементы, прослушиватели событий и т.д. в теневой DOM, используя обычные методы DOM.</li>
<li>При необходимости определите HTML template, используя {{htmlelement("template")}} и {{htmlelement("slot")}}. Снова используйте обычные методы DOM, чтобы клонировать шаблон и прикрепить его к вашей теневой DOM.</li>
<li>Используйте свой настраиваемый элемент везде, где хотите, на своей странице, как и любой обычный элемент HTML.</li>
</ol>
<h2 id="Учебники">Учебники</h2>
<dl>
<dt><a href="/ru/docs/Web/Web_Components/Using_custom_elements">Использование пользовательских элементов </a></dt>
<dd>Руководство, показывающее, как использовать функции настраиваемых элементов для создания простых веб-компонентов, а также рассказывает про обратные вызовы жизненного цикла и некоторые другие более сложные функции.</dd>
<dt><a href="/ru/docs/Web/Web_Components/Using_shadow_DOM">Использование shadow DOM</a></dt>
<dd>Руководство, которое рассматривает основы теневой DOM, показывает, как прикрепить теневую DOM к элементу, добавлять к теневому дереву DOM, стилизовать его и многое другое.</dd>
<dt><a href="/ru/docs/Web/Web_Components/Using_templates_and_slots">Использование шаблонов и слотов</a></dt>
<dd>Руководство, показывающее, как определить повторно используемую структуру HTML с помощью элементов {{htmlelement("template")}} и {{htmlelement ("slot")}}, а затем использовать эту структуру внутри ваших веб-компонентов.</dd>
</dl>
<h2 id="Справка">Справка</h2>
<h3 id="Пользовательские_элементы">Пользовательские элементы</h3>
<dl>
<dt>{{domxref("CustomElementRegistry")}}</dt>
<dd>Содержит функции, связанные с настраиваемыми элементами, в первую очередь с методом {{domxref("CustomElementRegistry.define()")}}, используемым для регистрации новых настраиваемых элементов, чтобы их можно было затем использовать в вашем документе.</dd>
<dt>{{domxref("Window.customElements")}}</dt>
<dd>Возвращает ссылку на объект <code>CustomElementRegistry</code>.</dd>
<dt><a href="/ru/docs/Web/Web_Components/Using_custom_elements#Использование_lifecycle_callbacks">Обратные вызовы жизненного цикла</a></dt>
<dd>Специальные функции обратного вызова, определенные внутри определения класса настраиваемого элемента, которые влияют на его поведение:
<ul>
<li><code>connectedCallback</code>: вызывается, когда настраиваемый элемент впервые подключается к DOM документа.</li>
<li><code>disconnectedCallback</code>: вызывается, когда пользовательский элемент отключается от DOM документа.</li>
<li><code>adoptedCallback</code>: вызывается, когда настраиваемый элемент перемещается в новый документ.</li>
<li><code>attributeChangedCallback</code>: вызывается при добавлении, удалении или изменении одного из атрибутов настраиваемого элемента.</li>
</ul>
</dd>
<dt>Расширения для создания пользовательских встроенных элементов</dt>
<dd>
<ul>
<li>Глобальный атрибут HTML {{htmlattrxref("is")}}: позволяет указать, что стандартный элемент HTML должен вести себя как зарегистрированный встроенный пользовательский элемент.</li>
<li>Параметр «is» метода {{domxref("Document.createElement()")}}: позволяет создать экземпляр стандартного HTML-элемента, который ведет себя как заданный зарегистрированный настраиваемый встроенный элемент.</li>
</ul>
</dd>
<dt>Псевдоклассы CSS</dt>
<dd>Псевдоклассы, относящиеся конкретно к настраиваемым элементам:
<ul>
<li>{{cssxref(":defined")}}: Соответствует любому заданному элементу, включая встроенные элементы и настраиваемые элементы, определенные с помощью <code>CustomElementRegistry.define()</code>.</li>
<li>{{cssxref(":host")}}: Выбирает теневой хост <a href="/ru/docs/Web/Web_Components/Using_shadow_DOM">теневого DOM</a>, содержащего CSS, внутри которого он используется.</li>
<li>{{cssxref(":host()")}}: Выбирает теневой хост <a href="/ru/docs/Web/Web_Components/Using_shadow_DOM">теневой DOM</a>, содержащий CSS, внутри которого он используется (так что вы можете выбрать пользовательский элемент изнутри его теневой DOM) - но только если селектор, указанный в качестве параметра функции, совпадает с теневым хостом.</li>
<li>{{cssxref(":host-context()")}}: Выбирает теневой хост <a href="/ru/docs/Web/Web_Components/Using_shadow_DOM">теневой DOM</a>, содержащий CSS, внутри которого он используется (так что вы можете выбрать пользовательский элемент изнутри его теневой DOM) - но только если селектор, указанный в качестве параметра функции, совпадает с предком(-ами) теневого хоста в том месте, где он находится внутри иерархии DOM.</li>
</ul>
</dd>
<dt>Псевдоэлементы CSS</dt>
<dd>Псевдоэлементы, относящиеся конкретно к настраиваемым элементам:
<ul>
<li>{{cssxref("::part")}}: Представляет любой элемент в <a href="/ru/docs/Web/Web_Components/Using_shadow_DOM">теневом дереве</a>, имеющий соответствующий атрибут {{HTMLAttrxRef("part")}}.</li>
</ul>
</dd>
</dl>
<h3 id="Shadow_DOM">Shadow DOM</h3>
<dl>
<dt>{{domxref("ShadowRoot")}}</dt>
<dd>Представляет корневой узел поддерева теневой модели DOM.</dd>
<dt>{{domxref("DocumentOrShadowRoot")}}</dt>
<dd>Миксин, определяющий функции, доступные для всех документов и теневых корневых узлов.</dd>
<dt>Расширения {{domxref("Element")}}</dt>
<dd>Расширения интерфейса <code>Element</code>, связанные с теневой DOM:
<ul>
<li>Метод {{domxref("Element.attachShadow()")}} прикрепляет теневое дерево DOM к указанному элементу.</li>
<li>Свойство {{domxref ("Element.shadowRoot")}} возвращает теневой корневой узел, прикрепленный к указанному элементу, или значение <code>null</code>, если корневой узел не прикреплен.</li>
</ul>
</dd>
<dt>Соответствующие дополнения {{domxref("Node")}}</dt>
<dd>Дополнения к интерфейсу <code>Node</code>, относящиеся к теневой DOM:
<ul>
<li>Метод {{domxref("Node.getRootNode()")}} возвращает корень объекта контекста, который необязательно включает теневой корневой узел, если он доступен.</li>
<li>Свойство {{domxref("Node.isConnected")}} возвращает логическое значение, указывающее, подключен ли узел (прямо или косвенно) к объекту контекста, например объект {{domxref("Document")}} в случае обычного DOM или {{domxref("ShadowRoot")}} в случае теневого DOM.</li>
</ul>
</dd>
<dt>Расширения {{domxref("Event")}}</dt>
<dd>Расширения интерфейса <code>Event</code>, относящиеся к теневой модели DOM:
<ul>
<li>{{domxref("Event.composed")}}: возвращает {{jsxref("Boolean")}}, который указывает, будет ли событие распространяться через границу теневой DOM в стандартную DOM (<code>true</code>) или нет (<code>false</code>).</li>
<li>{{domxref ("Event.composedPath")}}: возвращает путь к событию (объекты, для которых будут вызваны слушатели). Это не включает узлы в теневых деревьях, если теневой корневой узел был создан с закрытым {{domxref("ShadowRoot.mode")}}.</li>
</ul>
</dd>
</dl>
<h3 id="HTML_templates">HTML templates</h3>
<dl>
<dt>{{htmlelement("template")}}</dt>
<dd>Содержит фрагмент HTML, который не отображается при первоначальной загрузке содержащего документа, но может отображаться во время выполнения с помощью JavaScript, который в основном используется в качестве основы для структур настраиваемых элементов. Связанный интерфейс DOM - {{domxref("HTMLTemplateElement")}}.</dd>
<dt>{{htmlelement("slot")}}</dt>
<dd>Заполнитель внутри веб-компонента, который можно заполнить собственной разметкой, что позволяет создавать отдельные деревья DOM и представлять их вместе. Связанный интерфейс DOM - {{domxref("HTMLSlotElement")}}.</dd>
<dt>Глобальный HTML атрибут <code><a href="/ru/docs/Web/HTML/Global_attributes/slot">slot</a></code></dt>
<dd>Назначает слот элементу в теневом дереве теневого DOM.</dd>
<dt>{{domxref("Slotable")}}</dt>
<dd>Миксин, реализованный как узлами {{domxref("Element")}}, так и {{domxref("Text")}}, определяющий функции, которые позволяют им стать содержимым элемента {{htmlelement("slot")}}. Миксин определяет один атрибут, {{domxref("Slotable.assignedSlot")}}, который возвращает ссылку на слот, в который вставлен узел.</dd>
<dt>{{domxref("Element")}} extensions</dt>
<dd>Расширения интерфейса <code>Element</code>, относящиеся к слотам:
<ul>
<li>{{domxref("Element.slot")}}: Возвращает имя слота теневого DOM, прикрепленного к элементу.</li>
</ul>
</dd>
<dt>Псевдоэлементы CSS</dt>
<dd>Псевдоэлементы, относящиеся конкретно к слотам:
<ul>
<li>{{cssxref("::slotted")}}: Соответствует любому содержимому, вставленному в слот.</li>
</ul>
</dd>
<dt>Событие {{event("slotchange")}}</dt>
<dd>Вызывается для экземпляра {{domxref("HTMLSlotElement")}} (элемент {{htmlelement("slot")}}) при изменении узла(-ов), содержащихся в этом слоте.</dd>
</dl>
<h2 id="Примеры">Примеры</h2>
<p>Мы создаем ряд примеров в репозитории GitHub с <a href="https://github.com/mdn/web-components-examples">примерами веб-компонентов</a>. Со временем будет добавлено больше.</p>
<h2 id="Спецификации">Спецификации</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Спецификация</th>
<th scope="col">Статус</th>
<th scope="col">Комментарии</th>
</tr>
<tr>
<td>{{SpecName("HTML WHATWG","scripting.html#the-template-element","<template> element")}}</td>
<td>{{Spec2("HTML WHATWG")}}</td>
<td>Определение {{HTMLElement("template")}}.</td>
</tr>
<tr>
<td>{{SpecName("HTML WHATWG","custom-elements.html#custom-elements","custom elements")}}</td>
<td>{{Spec2("HTML WHATWG")}}</td>
<td>Определение <a href="/ru/docs/Web/Web_Components/Использование_пользовательских_элементов">пользовательских HTML элементов</a></td>
</tr>
<tr>
<td>{{SpecName("DOM WHATWG","#shadow-trees","shadow trees")}}</td>
<td>{{Spec2("DOM WHATWG")}}</td>
<td>Определение <a href="/ru/docs/Web/Web_Components/Using_shadow_DOM">Shadow DOM</a></td>
</tr>
<tr>
<td>{{SpecName("HTML Imports", "", "")}}</td>
<td>{{Spec2("HTML Imports")}}</td>
<td>Начальное определение <a href="/ru/docs/Web/Web_Components/HTML_Imports">HTML импорта</a></td>
</tr>
<tr>
<td>{{SpecName("Shadow DOM", "", "")}}</td>
<td>{{Spec2("Shadow DOM")}}</td>
<td>Начальное определение <a href="/ru/docs/Web/Web_Components/Using_shadow_DOM">Shadow DOM</a></td>
</tr>
</tbody>
</table>
<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2>
<p>В основном:</p>
<ul>
<li>Веб-компоненты по умолчанию поддерживаются в Firefox (версия 63), Chrome и Opera.</li>
<li>Safari поддерживает ряд функций веб-компонентов, но меньше, чем указанные выше браузеры.</li>
<li>Edge работает над реализацией.</li>
</ul>
<p>Для получения подробной информации о поддержке определенных функций браузером обратитесь к перечисленным выше справочным страницам.</p>
<h2 id="Смотрите_также">Смотрите также</h2>
<ul>
<li><a href="https://www.webcomponents.org/">webcomponents.org</a> - сайт с примерами веб-компонентов, учебными пособиями и другой информацией.</li>
<li><a href="https://fast.design/" rel="noopener">FAST</a> - это библиотека веб-компонентов, созданная Microsoft, которая предлагает несколько пакетов для использования в зависимости от потребностей вашего проекта. <a href="https://github.com/microsoft/fast/tree/master/packages/web-components/fast-element" rel="noopener">Fast Element</a> - это легкое средство для простого создания производительных, эффективных с точки зрения памяти и совместимых со стандартами веб-компонентов. <a href="https://github.com/microsoft/fast/tree/master/packages/web-components/fast-foundation" rel="noopener">Fast Foundation</a> - это библиотека классов, шаблонов и других утилит веб-компонентов, построенная на основе fast-element, предназначенная для создания зарегистрированных веб-компонентов.</li>
<li><a href="https://github.com/hybridsjs/hybrids">Hybrids</a> - библиотека веб-компонентов с открытым исходным кодом, которая предпочитает простые объекты и чистые функции <code>class</code> и <code>this</code> синтаксису. Он предоставляет простой и функциональный API для создания пользовательских элементов.</li>
<li><a href="https://www.polymer-project.org/">Polymer</a> - каркас веб-компонентов Google - набор полифилов, улучшений и примеров. На данный момент самый простой способ кроссбраузерно использовать веб-компоненты.</li>
<li><a href="https://github.com/devpunks/snuggsi#readme">Snuggsi</a> - Простые веб-компоненты размером ~ 1 КБ, <em>включая полифил</em> - Все, что вам нужно, это браузер и базовое понимание классов HTML, CSS и JavaScript для продуктивной работы.</li>
<li><a href="https://github.com/slimjs/slim.js">Slim.js</a> - библиотека веб-компонентов с открытым исходным кодом - высокопроизводительная библиотека для быстрой и простой разработки компонентов; расширяемая, подключаемая и кросс-платформенная.</li>
<li><a href="https://stenciljs.com/">Stencil</a> - набор инструментов для создания многоразовых масштабируемых систем проектирования в веб-компонентах.</li>
</ul>
|