Кратко
СкопированоShadow — это корневой узел Shadow DOM, который создаёт изолированное дерево DOM, отделённое от основного документа. Позволяет инкапсулировать стили и структуру кастомных элементов.
Пример
Скопировано
class MyCard extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <style> :host { display: block; border: 1px solid #ccc; padding: 16px; border-radius: 8px; } .title { font-weight: bold; color: #333; } </style> <div class="title"> <slot name="title">Заголовок</slot> </div> <div class="content"> <slot>Содержимое карточки</slot> </div> `; }}customElements.define('my-card', MyCard);
class MyCard extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
:host {
display: block;
border: 1px solid #ccc;
padding: 16px;
border-radius: 8px;
}
.title {
font-weight: bold;
color: #333;
}
</style>
<div class="title">
<slot name="title">Заголовок</slot>
</div>
<div class="content">
<slot>Содержимое карточки</slot>
</div>
`;
}
}
customElements.define('my-card', MyCard);
<my-card> <span slot="title">Моя карточка</span> <p>Это содержимое карточки</p></my-card>
<my-card>
<span slot="title">Моя карточка</span>
<p>Это содержимое карточки</p>
</my-card>
Как пишется
Скопировано
// Создание ShadowRootconst shadow = element.attachShadow({ mode: 'open' });// Доступ к существующему ShadowRootconst shadowRoot = element.shadowRoot;// Работа с содержимымshadowRoot.innerHTML = '<div>Содержимое</div>';shadowRoot.appendChild(element);
// Создание ShadowRoot
const shadow = element.attachShadow({ mode: 'open' });
// Доступ к существующему ShadowRoot
const shadowRoot = element.shadowRoot;
// Работа с содержимым
shadowRoot.innerHTML = '<div>Содержимое</div>';
shadowRoot.appendChild(element);
Параметры attachShadow()
Скопированоmode— режим доступа:open— ShadowRoot доступен черезelement. shadow Root closed— ShadowRoot недоступен извне
Свойства
Скопировано-
СкопированоactiveElement
Возвращает элемент в Shadow Tree, который имеет фокус.
const focusedElement = shadowRoot.activeElement;console.log(focusedElement); // Элемент с фокусом или null
const focusedElement = shadowRoot.activeElement;
console.log(focusedElement); // Элемент с фокусом или null
-
СкопированоadoptedStyle Sheets
Массив конструктивных таблиц стилей для использования в Shadow DOM.
const stylesheet = new CSSStyleSheet();stylesheet.replaceSync('div { color: red; }');shadowRoot.adoptedStyleSheets = [stylesheet];
const stylesheet = new CSSStyleSheet();
stylesheet.replaceSync('div { color: red; }');
shadowRoot.adoptedStyleSheets = [stylesheet];
-
Скопированоclonable
Булево значение, указывающее, можно ли клонировать ShadowRoot.
console.log(shadowRoot.clonable); // true или false
console.log(shadowRoot.clonable); // true или false
-
СкопированоdelegatesFocus
Булево значение, указывающее, делегирует ли ShadowRoot фокус при выборе нефокусируемого узла.
console.log(shadowRoot.delegatesFocus); // true или false
console.log(shadowRoot.delegatesFocus); // true или false
-
СкопированоfullscreenElement
Элемент, который в данный момент находится в полноэкранном режиме в этом Shadow Tree.
const fullscreenEl = shadowRoot.fullscreenElement;console.log(fullscreenEl); // Элемент в полноэкранном режиме или null
const fullscreenEl = shadowRoot.fullscreenElement;
console.log(fullscreenEl); // Элемент в полноэкранном режиме или null
-
Скопированоhost
Возвращает ссылку на DOM-элемент, к которому прикреплён ShadowRoot.
const hostElement = shadowRoot.host;console.log(hostElement); // Элемент-хост
const hostElement = shadowRoot.host;
console.log(hostElement); // Элемент-хост
-
СкопированоinnerH T M L
Устанавливает или возвращает содержимое ShadowRoot.
// Получение содержимогоconsole.log(shadowRoot.innerHTML);// Установка содержимогоshadowRoot.innerHTML = '<div>Новое содержимое</div>';
// Получение содержимого
console.log(shadowRoot.innerHTML);
// Установка содержимого
shadowRoot.innerHTML = '<div>Новое содержимое</div>';
-
Скопированоmode
Режим ShadowRoot: open или closed.
console.log(shadowRoot.mode); // 'open' или 'closed'
console.log(shadowRoot.mode); // 'open' или 'closed'
-
СкопированоpictureIn Picture Element
Элемент в Shadow Tree, который в данный момент представлен в режиме "картинка в картинке".
const pipElement = shadowRoot.pictureInPictureElement;console.log(pipElement); // Элемент в PiP режиме или null
const pipElement = shadowRoot.pictureInPictureElement;
console.log(pipElement); // Элемент в PiP режиме или null
-
Скопированоserializable
Булево значение, указывающее, можно ли сериализовать ShadowRoot.
console.log(shadowRoot.serializable); // true или false
console.log(shadowRoot.serializable); // true или false
-
СкопированоslotAssignment
Тип назначения слотов: manual или named.
console.log(shadowRoot.slotAssignment); // 'manual' или 'named'
console.log(shadowRoot.slotAssignment); // 'manual' или 'named'
-
СкопированоstyleSheets
Список CSS объектов для таблиц стилей в Shadow Tree.
const stylesheets = shadowRoot.styleSheets;console.log(stylesheets.length); // Количество таблиц стилей
const stylesheets = shadowRoot.styleSheets;
console.log(stylesheets.length); // Количество таблиц стилей
Методы
Скопировано-
СкопированоgetAnimations ( )
Возвращает массив всех активных анимаций в Shadow Tree.
const animations = shadowRoot.getAnimations();animations.forEach(animation => { console.log(animation.animationName);});
const animations = shadowRoot.getAnimations();
animations.forEach(animation => {
console.log(animation.animationName);
});
События
СкопированоShadowRoot поддерживает события через всплытие от HTML:
-
Скопированоslotchange
Событие, которое срабатывает при изменении содержимого слота.
shadowRoot.addEventListener('slotchange', (event) => { console.log('Содержимое слота изменилось');});
shadowRoot.addEventListener('slotchange', (event) => {
console.log('Содержимое слота изменилось');
});
Как понять
СкопированоShadow создаёт изолированное дерево DOM, которое:
- Инкапсулирует стили — CSS внутри Shadow DOM не влияет на внешние элементы
- Скрывает структуру — внутренние элементы недоступны из основного DOM
- Обеспечивает переиспользование — компонент работает независимо от контекста
Основные концепции:
Скопировано- Хост-элемент — элемент, к которому прикреплён ShadowRoot
- Shadow Tree — дерево DOM внутри ShadowRoot
- Light DOM — обычные дочерние элементы хост-элемента
- Слоты — точки вставки Light DOM в Shadow Tree
Подсказки
Скопировано💡 Доступ к ShadowRoot возможен только если mode.
💡 Используйте <slot> для вставки Light DOM в Shadow Tree.
💡 Стили в Shadow DOM не проникают наружу, но внешние стили могут влиять на :host.
💡 Используйте mode для отладки, mode для максимальной инкапсуляции.
- Chrome 53, поддерживается
- Edge 79, поддерживается
- Firefox 63, поддерживается
- Safari 10, поддерживается