Назад к вопросам

Ответ от нейросети

sobes.tech AI

Shadow DOM - это веб-стандарт, позволяющий инкапсулировать HTML, CSS и JavaScript в отдельные, изолированные от основного документа блоки.

Основные концепции:

  • Shadow Host: Элемент DOM, к которому прилагается Shadow DOM.
  • Shadow Tree: Изолированное поддерево DOM.
  • Shadow Boundary: Граница между Shadow DOM и основным документом.
  • Shadow Root: Корневой узел Shadow Tree. Создается с помощью element.attachShadow({ mode: 'open' | 'closed' }):
    • open: Shadow Root доступен извне через element.shadowRoot.
    • closed: Shadow Root не доступен извне.

Преимущества:

  • Инкапсуляция стилей: Стили, определенные в Shadow DOM, не просачиваются наружу и не влияют на основной документ. Стили из основного документа по умолчанию не влияют на Shadow DOM, но это можно контролировать.
  • Инкапсуляция DOM: Элементы внутри Shadow DOM не видны в основном DOM-дереве, что предотвращает случайное пересечение селекторов и манипуляций.
  • Инкапсуляция поведения: Логика и обработчики событий могут быть изолированы в Shadow DOM.

Пример создания Shadow DOM:

// Создаем новый элемент DIV
const hostElement = document.createElement('div');
// Прикрепляем Shadow DOM к элементу
const shadowRoot = hostElement.attachShadow({ mode: 'open' });

// Добавляем содержимое в Shadow DOM
shadowRoot.innerHTML = `
  <style>
    /* Стиль, применимый только внутри этого Shadow DOM */
    p {
      color: blue;
    }
  </style>
  <p>Это текст внутри Shadow DOM</p>
`;

// Добавляем хост-элемент в основной документ
document.body.appendChild(hostElement);

Применение:

  • Создание переиспользуемых веб-компонентов.
  • Изоляция стилей сторонних библиотек.
  • Защита внутренних деталей компонента от внешнего вмешательства.

Особенности работы со стилями:

  • Внешние стили по умолчанию не влияют на Shadow DOM.
  • 可以用 :host псевдо-класс для стилизации самого Shadow Host изнутри Shadow DOM.
  • 可以使用 :host-context() для стилизации на основе контекста Shadow Host.
  • 可以使用 ::slotted() псевдо-элемент для стилизации элементов, помещенных в слоты ( <slot> ).
<my-component>
  <!-- Этот элемент будет "отправлен" в слот внутри Shadow DOM -->
  <span>Слот контент</span>
</my-component>
// Внутри Shadow DOM компонента my-component
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
  <style>
    /* Стиль для элемента, помещенного в слот с именем "my-slot" */
    ::slotted(span) {
      font-weight: bold;
    }
  </style>
  <div>Основное содержимое компонента</div>
  <slot></slot> <!-- Здесь будет отображен слот контент -->
`;

Shadow DOM является частью спецификации Web Components.