Кратко
Скопировано.attach
— это метод, который позволяет создать и прикрепить Shadow DOM к HTML-элементу. Он используется в веб-компонентах для инкапсуляции структуры и стилей.
Пример
Скопировано<template id="my-box-template"> <style> :host { display: block; padding: 1em; background: lightgray; border-radius: 6px; } </style> <slot></slot></template><my-box>Содержимое бокса</my-box><script>class MyBox extends HTMLElement { constructor() { super() const shadowRoot = this.attachShadow({ mode: 'open' }) const template = document.getElementById('my-box-template') shadowRoot.appendChild(template.content.cloneNode(true)) }}customElements.define('my-box', MyBox)</script>
<template id="my-box-template"> <style> :host { display: block; padding: 1em; background: lightgray; border-radius: 6px; } </style> <slot></slot> </template> <my-box>Содержимое бокса</my-box> <script> class MyBox extends HTMLElement { constructor() { super() const shadowRoot = this.attachShadow({ mode: 'open' }) const template = document.getElementById('my-box-template') shadowRoot.appendChild(template.content.cloneNode(true)) } } customElements.define('my-box', MyBox) </script>
Как пишется
Скопированоelement.attachShadow({ mode: 'open' })
element.attachShadow({ mode: 'open' })
Метод принимает объект с опциями:
mode
: (обязательно)open
(по умолчанию) илиclosed
. В режимеopen
можно получить доступ к.shadow
извне. ВRoot closed
— нет.delegates
: (опционально)Focus true
, если нужно передавать фокус внутрь компонента.slot
: (опционально)Assignment named
илиmanual
— режим работы со слотами (по умолчаниюnamed
).clonable
,serializable
: (опционально) экспериментальные, пока редко используются.
Как понять
СкопированоЕсли вы создаёте свой HTML-элемент (custom
), то скорее всего захотите добавить Shadow DOM для:
- изоляции CSS от внешней среды;
- использования слотов (
<slot>
) для вставки содержимого; - лучшего контроля над внутренней структурой компонента.
Без вызова .attach
компонент остаётся обычным элементом.
Анонимный компонент
СкопированоЭто такой компонент, который объявлен с помощью HTML
. Например:
class MyBox extends HTMLElement { ... }customElements.define('my-box', MyBox)
class MyBox extends HTMLElement { ... } customElements.define('my-box', MyBox)
Но уже вот такой компонент НЕ считается анонимным:
class MySection extends HTMLSectionElement { ... }customElements.define('my-section', MySection)
class MySection extends HTMLSectionElement { ... } customElements.define('my-section', MySection)
Он не считается анонимным из-за того, что он объявлен как HTML-элемент <section>
.
Подсказки
Скопировано💡 Shadow DOM — отличный способ инкапсуляции, но не подходит, если вам нужно, чтобы внешние стили влияли на компонент.
💡 Если Shadow DOM в режиме closed
, то получить его через element
будет невозможно — даже из консоли.
- Chrome 53, поддерживается
- Edge 79, поддерживается
- Firefox 63, поддерживается
- Safari 10, поддерживается