Что такое shadow root
Shadow DOM
Итак, что же такое shadow DOM:
Shadow DOM (или теневая модель документа) — часть документа, реализующая инкапсуляцию в DOM дереве. Она (теневая модель) является частью документа и встраивается непосредственно внутрь страницы.
Для упрощения отладки shadow DOM, в хроме можно включить отображение в веб-инспекторе (Settings — General — Show shadow DOM).
Надо заметить, что в стандарте реализуемая инкапсуляция называется функциональной, поскольку shadow DOM встраивается в документ и является одной из многих его частей, работающих «независимо» (более-менее независимо) друг от друга. Соответственно, при проектировании реализации, нужно было установить функциональные границы в дереве документа, чтобы как-то оперировать с множеством таких «независимых» фрагментов. Для решения проблемы инкапсуляции, и была введена новая абстракция — shadow DOM, позволяющая создавать несколько DOM деревьев в пределах одного родительского дерева и был разработан документ, описывающий ее.
Дочернее дерево размещается внутри некоторого элемента на странице. Функциональные границы между главным деревом документа и теневым называются shadow boundaries (теневые границы). Элемент, который размещает в себе теневое дерево, называется shadow host, а корень теневого дерево, соответственно, называется shadow root.
Во время рендеринга shadow tree занимает место содержимого shadow host (элемента).
Пример реализации в chromium:
Insertion points
Для композиции потомков shadow host и shadow tree используются insertion points. Insertion points определяют местонахождение потомков shadow host в shadow tree. При рендеринге shadow tree потомки проецируются в это место. Механизм, определяющий какие потомки shadow host будут спроецированы в insertion point называется distribution.
Псевдо-элемент ::distributed()
::distributed(selector) — функциональный псевдо-элемент принимающий относительный селектор в качестве аргумента. Он представляет отношение между insertion point в shadow tree и элементом, перенесенным в insertion point.
Реализация (chrome canary only):
Один shadow host может вмещать в себя несколько shadow tree — они будут отображены в порядке их добавления. Такой набор деревьев называется shadow stack. Более «старый» shadow tree так же можно переносить в другой shadow tree посредством shadow insertion point.
Reprojection (перепроецирование)
Перепроецирование это ситуация, при которой первое shadow tree уже имеет insertion point, а второй shadow tree имеет shadow insetion point, при этом контент, взятый из shadow host сначала проецируется в первом shadow tree, а затем во втором.
Псевдо-элементы (в контексте shadow DOM)
In certain situations, the author of a shadow tree may wish to designate one or more elements from that tree as a structural abstraction that provides additional information about the contents of the shadow tree.
В определенных ситуациях, автору shadow tree захочется назначить один или несколько элементов из shadow tree как стукртурную абстракцию, дающую дополнительную информацию о контенте shadow tree.
Что я понимаю как возможность использовать css селекторы вне shadow tree для доступа к элементам внутри него:
События
Некоторые события пропускаются через shadow boundary, некоторые нет. Исключение составляют mutation events — они вообще не должны возникать в shadow tree и, соответственно, переходить через shadow boundary. При прохождении события через shadow boundary у него меняется event.target для поддержания инкапсуляции.
Вот интересный пример:
События спроецированного элемента всплывают в shadow host, как-будто он все еще находится непосредственно внутри shadow host. События first-inner-element не всплывают в shadow host, в отличие от second-inner-element, который абсолютно спозиционирован и вынесен за пределы shadow host (при этом event.target сменился).
Стили
Есть два метода, позволяющие манипулировать стилями shadow tree:
shadowRoot.resetStyleInheritance (false by default)
Сбрасывает наследование стилей для shadow tree (стили снаружи не применяются на shadow tree).
shadowRoot.applyAuthorStyles (false by default)
Применяет стили авторского (главного) документа.
Можно сказать, что некоторой «инкапсуляции» для html не хватало. Это открывает большие возможности по созданию и шаблонизации различных, заранее подготовленных, виджетов на странице. Удивляет только отсутствие инкапсуляции JavaScript кода внутри виджетов, хотя мне казалось бы это довольно логичным.
Про Shadow DOM
Какие основные вопросы решает Shadow DOM?
Инкапсуляция. Внутри Shadow DOM создается отдельный «поддокумент», к которому можно применять свои стили, экранированные от воздействий внешней среды (вам не нужно писать многоэтажные имена классов, чтобы обезопасить ваш элемент или внешний документ от «протечек») и где создается свой контекст для методов DOM API, где, к примеру, с помощью селекторов можно получить только те элементы которые находятся внутри и остаются почти невидимыми снаружи (при этом, допустимо использование одинаковых ID у элементов в разных контекстах, без опасности все поломать).
Теперь у нашего div есть реакция на наведение мыши при том, что мы не создавали для этого никаких классов и не вносили никаких изменений во внешние стили. Shadow DOM дает нам доступ к своему элементу-контейнеру через селектор :host, и используя этот селектор, мы можем создавать любые сложные стили для элемента в JS. Прошу принять во внимание, что код приведенный выше, написан исключительно для демонстрации самого принципа, в бою все может выглядеть немного иначе.
Когда стоит применять Shadow DOM?
Думаю, основными областями применения можно считать те-же, что и для веб-компонентов в целом: для создания встраиваемых виджетов и UI-библиотек-агностиков, минимально зависимых от конкретных мета-платформ, экосистем и фреймворков. Везде, где важна инкапсуляция, возможность спрятать «под ковер» реализацию и удобная независимая композиция.
Модные микрофронтенды также являются интересной областью для применения возможностей Shadow DOM.
Также, можно рассмотреть вариант применения в случаях, когда вам необходимо внедрить свое локальное решение в большой и неповоротливый проект с кучей легаси-кода, в котором можно закопаться неоправданно надолго и есть опасность сломать что-то неочевидное: изоляция участка может оказаться быстрым и эффективным решением.
Вялотекущий рефакторинг сложной системы тоже можно проводить через создание «островков безопасности».
Какие могут возникнуть сложности?
Следует понимать, что Shadow DOM в отдельности, НЕ решает вопрос контроля жизненного цикла ваших компонентов и инициализации компонентов во внешней среде (помните, для этого есть Custom Elements).
Shadow DOM в документе может быть создан только через JavaScript, а потому, вы не сможете напрямую использовать предварительный рендер (SSR) для внутренней разметки. Данное ограничение можно обойти, но это отдельный непростой разговор.
На создание Shadow DOM, при прочих равных условиях, уходят дополнительные ресурсы, поэтому, если для вас важен вопрос производительности, старайтесь не использовать теневые участки DOM бездумно повсюду. Часто для создания виджета достаточно всего одного общего теневого DOM, без лишней вложенности и сопутствующих этому дополнительных расходов.
Вывод
Что такое Shadow DOM?
Ранее я написал статью «Что такое DOM?» Напомним, что объектная модель документа является представление HTML документа в виде дерева объектов. Оно используется браузерами для определения того, что отображать на странице, и кодом Javascript для изменения содержимого, структуры или стиля страницы.
Для примера взглянем на следующий HTML документ:
Этот документ может быть представлен в виде DOM дерева.
Вы, возможно, слышали о таких терминах, как «Shadow DOM» и «Virtual DOM». Хотя они, конечно, связаны с оригинальным DOM, но по сути своей это совершенно разные концепции. В этой статье я расскажу, что конкретно представляет собой теневой DOM и чем он отличается от исходного DOM. В следующей статье я расскажу что такое виртуальный DOM.
Все вокруг глобально 👍🏾! Стоп, все глобально 👎🏾
Все элементы и стили в HTML-документе и, следовательно, в DOM, находятся в одной большой глобальной области. Любой элемент на странице может быть доступен с помощью метода document.querySelector(), независимо от того, насколько глубоко он вложен в документ или где он находится. Точно так же CSS, примененный к документу, может выбрать любой элемент, независимо от того, где он находится.
Такое поведение может быть очень удобным, если мы хотим применить стили ко всему документу. Невероятно полезно иметь возможность выбирать каждый отдельный элемент на странице и устанавливать, например, их размеры одной строкой.
С другой стороны, бывают случаи, когда элемент требует полной изоляции, и мы не хотим, чтобы на него влияли даже глобальные стили. Хорошим примером этого являются сторонние виджеты, такие как кнопка «Follow» для Twitter на некоторых страницах.
Такая кнопка может отображаться как обычная ссылка
DOM внутри DOM
Вы можете думать о теневом DOM как о «DOM внутри DOM». Это собственное изолированное дерево DOM со своими элементами и стилями, полностью изолированное от исходного DOM.
Хотя только недавно его стали использовать программисты, теневой DOM годами использовался пользовательскими агентами для создания и оформления сложных компонентов, таких как элементы формы. Для примера возьмем элемент ввода диапазона. Чтобы создать его на странице, все, что нам нужно сделать, это добавить следующий элемент:
Если мы посмотрим глубже, мы увидим, что этот один элемент фактически состоит из нескольких меньших элементов
Как работает shadow DOM
Сначала мы начнем с shadow host (теневого хоста). Это обычный элемент HTML в исходном DOM, к которому мы хотим присоединить новый теневой DOM. Для такого компонента, как кнопка «Follow», он также может содержать запасной элемент, который мы хотели бы отобразить, если Javascript не был включен на странице или теневой DOM не поддерживается.
Это создаст пустой shadow root (теневой корень) как дочерний элемент нашего теневого хоста. Теневой корень — это начало нового теневого DOM, так же, как элемент является началом исходного DOM. Мы можем увидеть наш теневой корень в инспекторе devtools с помощью #shadow-root.
Хотя теперь дочерние элементы HTML видны в инспекторе, они больше не видны на странице, так как заработал теневой корень.
Далее мы добавим этот новый элемент в нашу теневую DOM так же, как добавляем любой элемент в качестве дочернего элемента к другому с помощью метода appendChild().
На данный момент, наш элемент должен выглядет как то так:
Наконец, мы можем добавить несколько стилей, создав элемент и добавив его к теневому корню.
В итоге наш элемент должен выглядеть как то так:
DOM против shadow DOM
В некотором смысле, теневой DOM является «облегченной» версией DOM. Как и DOM, он является представлением элементов HTML, которое используется для определения того, что следует отображать на странице, и позволяет изменять элементы. Но в отличие от DOM, теневой DOM не использует глобальные стили документа. Теневой DOM, как следует из названия, всегда присоединен к элементу в обычном DOM. Без базовых элементов DOM, теневой DOM не существует.
Введение в Shadow DOM
Russian (Pусский) translation by AlexBioJS (you can also view the original English article)
Инкапсуляция – один из китов, на которые опирается парадигма объектно-ориентированного программирования, и обычно используется для ограничения внутреннего представления объекта от внешнего мира.
Возвращаясь к нашей проблеме, скажу, что мы безусловно можем инкапсулировать код JavaScript при помощи замыканий или паттерна модуль, однако можем ли мы применить этот же подход и к разметке HTML? Представьте, что нам необходимо создать виджет UI (* пользовательский интерфейс); можем ли мы скрыть детали реализации нашего виджета от кода JavaScript и CSS, подключенного на странице, который пользуется нашим виджетом? Или наоборот, можем ли мы предотвратить нарушение работы нашего виджета или нарушения его внешнего вида из-за влияния кода, который пользуется нашим виджетом.
Решение проблемы при помощи Shadow DOM
Единственное решение, при котором создается граница между написанным вами кодом и кодом, который его использует, довольно безобразное и заключается в использовании громоздкого элемента iFrame, многие атрибуты которого считаются устаревшими (* является дочерним контекстом для браузера, за счет которого в текущую страницу встраивается другая страница HTML). Так должны ли мы всегда приспосабливаться к этому подходу?
Уже нет! Shadow DOM предоставляет нам элегантный способ перекрытия обычного поддерева DOM специальным фрагментом документа (* интерфейс DocumentFragment представляет собой минимальный объект документа, у которого нет родителя. Используется для хранения сегмента структуры документа, состоящей из узлов. Поскольку он не является частью древовидной структуры активного документа, то изменения, внесенные во фрагмент, не влияют на документ), который содержит другое дерево узлов, недоступных для скриптов и стилей. Интересно то, что это вовсе не новинка! Различные браузера уже использовали эту методологию для реализации нативных виджетов вроде date (* виджет для выбора времени), sliders (* слайдер), audio (* аудиоплеер), video player (* видеоплеер) и т.д.
Активируем показ Shadow DOM
На момент написания этого руководства текущая версия Chrome (v29) поддерживает инспектирование Shadow DOM при помощи Chrome DevTools. Откройте Devtools и нажмите кнопку с иконкой зубчиков шестеренки справа внизу экрана для открытия панели Settings, прокрутите бегунок немного вниз и увидите флажок для активации показа Shadow DOM.
Теперь, когда мы активировали его в нашем браузере, давайте ознакомимся с внутренним устройством аудиоплеера по умолчанию. Просто введите:
в вашу HTML-разметку. Благодаря нему показывается следующий нативный аудиоплеер в браузерах, что его поддерживают:
Теперь давайте, проинспектируйте этот виджет аудиоплеера, который только что создали. Вау!
В инспекторе показывается внутренняя организация аудиоплеера, которую без активации показа Shadow DOM было скрыто. Как мы видим в элементе audio используется фрагмент документа для размещения внутреннего контента виджета и его добавления в элемент-контейнер (известный как Shadow Host).
Shadow Host и Shadow Root
После выполнения кода для добавления Shadow DOM дерево Shadow заменяет контент Shadow Host.
Этот процесс перекрытия узлов часто называют композицией (* в ООП – метод создания нового объекта путём объединения старых и новых частей, в противоположность наследованию).
Hello Shadow DOM World (* первая простейшая программа, которую создают новички в области компьютерных наук)
Хватит болтовни, давайте приступим к написанию некоторого кода. Предположим, что у нас имеется следующая разметка, при помощи которой показывается простое сообщение с приветствием.
Добавьте следующий код JavaScript или воспользуйтесь Fiddle (* фрагмент кода HTML, CSS или JavaScript, размещаемый в онлайн сообществе JSFiddle):
Обратите внимание на префикс, специфичный для определенного производителя браузеров, – webkit перед именем функции. Он указывает на то, что эта функциональная возможность (* Shadow DOM) сейчас поддерживается только в некоторых браузерах, работающих на основе webkit (* движок браузера).
Если бы вы выполнили код этого примера в браузере с поддержкой Shadow DOM, то увидели бы «Hello Shadow DOM World» вместо «Welcome to My World», поскольку узлы Shadow DOM перекрыли бы обычные.
Оговорка: Как некоторые из вас могли заметить, мы смешиваем разметку с кодом скрипта, что обычно не рекомендуется, и Shadow DOM не является исключением. Мы преднамеренно не использовали шаблоны сейчас (* позволяет вам объявлять фрагменты DOM, которые подвергаются парсингу, неактивны при загрузке страницы и могут быть активированы позже при выполнении кода), чтобы избежать путаницы. Shadow DOM также предоставляет нам решение этой проблемы, и мы рассмотрим его очень скоро.
Некоторые сведения относительно Shadow Boundary
Если вы попробуете обратиться к контенту отображенного дерева при помощи JavaScript следующим образом:
то получите изначальный контент «Welcome to My World», а не контент, который собственно отображается на странице, поскольку дерево Shadow DOM инкапсулировано от любых скриптов. Это также означает, что виджет, который вы создаете при помощи Shadow DOM, защищен от влияния любых нежелательных/несовместимых скриптов, уже присутствующих на странице.
Инкапсуляция стилей
Подобным образом, пересечение Shadow Boundary любым селектором CSS запрещено. Ознакомьтесь со следующим кодом, в котором мы применили к элементам списка красный цвет, однако этот стиль применяется только к узлам, которые являются частью родительской страницы, и на элементы списка, которые являются частью Shadow Root, он не влияет.
Вы можете увидеть код в действии на Fiddle. Подобная инкапсуляция срабатывает даже если мы меняем направление обхода дерева (* при применении стилей). Любые стилевые правила, определенные внутри Shadow DOM, не влияют на родительский документ и остаются только в области видимости Shadow Root. Ознакомьтесь с этим Fiddle в качестве примера, где мы применяем синий цвет к элементам списка в Shadow DOM, однако на элементы списка родительского документа этот стиль не влияет.
Но при этом имеется одно примечательное исключение; Shadow DOM предоставляет нам возможность задать стилевое оформление для Shadow Host, узла DOM, в котором располагается Shadow DOM. В идеале этот узел располагается за пределами Shadow Boundary и не является частью Shadow Root, однако за счет использования правила @host мы можем добавить стилевое оформление к Shadow Host так, как мы сделали для сообщения с приветствием в примере ниже.
Ознакомьтесь с этим Fiddle, где мы добавили стилевое оформление для сообщения с приветствием в Shadow Host при помощи стилевых правил, заданных в Shadow DOM.
Создание зацепок (* специальная точка входа; место в программе, куда можно подсоединить дополнительный код (обычно для расширения ее функциональных возможностей)) для добавления стилевого оформления
Как разработчик виджета я мог бы захотеть, чтобы у пользователя моего виджета была возможность добавить собственное стилевое оформление для определенных элементов. Это реализуемо за счет добавления дырки в Shadow Boundary при помощи пользовательских псевдо-элементов (* элемент DOM внутри Shadow Root пользовательского элемента, для которого автор явно добавил возможность задания правил стилевого оформления из-за пределов Shadow Root при помощи псевдо-селекторов). Это подобно тому, как некоторые браузера предоставляют разработчикам зацепки для добавления стилевого оформления к некоторым внутренним элементам нативного виджета. Например для того чтобы добавить стилевое оформление для ползунка и линейки нативного слайдера, вы можете использовать ::-webkit-slider-thumb и ::webkit-slider-runnable-track следующим образом:
Форкните (* создайте собственную копию) этого Fiddle и добавьте собственное стилевое оформление к нему.
Переориентация события
Если событие, которое возникает на одном из узлов Shadow DOM, пересекает Shadow Boundary, то оно переориентируется таким образом, чтобы относиться к Shadow Host для сохранения инкапсуляции. Рассмотрим следующий код:
Разделяем то, о чем нужно будет позаботиться
Мы уже знаем, что всегда следует разделять собственно контент и его представления; в Shadow DOM не должен содержаться никакой контент, который необходимо в итоге показать пользователю. Вместо этого контент должен всегда располагаться на исходной странице, а не скрываться в шаблоне Shadow DOM. При выполнении композиции этот контент затем должен быть спроецирован в соответствующую точку вставки (* место в документе, где будут выполняться некоторые действия), указанную в шаблоне Shadow DOM. Давайте перепишем наш пример «Hello World», помня о вышеупомянутом разделении; с рабочим примером можете ознакомиться на Fiddle.
Ознакомьтесь с рабочим примером и поэкспериментируйте с ним, чтобы лучше понять концепцию точек вставки и проецирования.
Web Components
Как вы уже, скорее всего, знаете, Shadow DOM – часть спецификации Web Components, которая предлагает и другие изящные инструменты вроде:
Я не буду долго болтать о других аспектах спецификации Web Components в этом руководстве, однако хорошо, если мы будем помнить, что вместе они позволяют нам создавать виджеты UI, которые можно повторно использовать и которые выглядят одинаково в различных браузерах, а также полностью инкапсулированы от всех скриптов и стилей страницы, которая использует их.
Заключение
В настоящий момент только Chrome и Opera поддерживают эту технологию, так что я был бы настороже при добавлении какого-либо Shadow DOM в мои конечные работы, однако учитывая то, что Google предоставляет Polymer, работающий на основе Web Components, и Polyfills (* polyfill – тип прокладки, которая добавляет в старые браузеры поддержку возможностей, которые в современных браузерах являются встроенными), предназначенный для нативной поддержки Shadow DOM браузерами, эту технологию должен осваивать каждый веб-разработчик.
Вы также можете следить за событиями, происходящими в мире Shadow DOM, подписавшись на канал Google+ Channel. Также ознакомьтесь с инструментом Shadow DOM Visualizer (* визуализатор работы Shadow DOM), который помогает вам визуализировать то, как Shadow DOM отображается в браузере.
Как работает JS: технология Shadow DOM и веб-компоненты
Сегодня, в переводе 17 части материалов, посвящённых особенностям всего, что так или иначе связано с JavaScript, речь пойдёт о веб-компонентах и о различных стандартах, которые направлены на работу с ними. Особое внимание здесь будет уделено технологии Shadow DOM.
Обзор
Веб-компоненты — это семейство API, предназначенных для описания новых элементов DOM, подходящих для повторного использования. Функционал таких элементов отделён от остального кода, их можно применять в веб-приложениях собственной разработки.
Существует четыре технологии, относящиеся к веб-компонентам:
Технология Shadow DOM
Тут предполагается, что вы уже знакомы с концепцией DOM и с соответствующими API. Если это не так — можете почитать этот материал.
Shadow DOM — это, в целом, то же самое, что и обычный DOM, но с двумя отличиями:
Это изолированное поддерево называют shadow tree (теневое дерево). Элемент, к которому присоединено такое дерево, называется shadow host (теневой хост-элемент). Всё, что добавляется в теневое поддерево DOM, оказывается локальным для элемента, к которому оно присоединено, в том числе — стили, описываемые с помощью тегов Launch
Шаблоны
Если включить такую конструкцию в состав HTML-разметки страницы, содержимое описываемого ей тега
не появится на экране до тех пор, пока не будет явным образом присоединено к DOM документа. Например, это может выглядеть так:
Существуют и другие средства, позволяющие достичь того же эффекта, но, как уже было сказано, шаблоны — очень удобный стандартный инструмент, пользующийся хорошей поддержкой браузеров.
Поддержка HTML-шаблонов современными браузерами
Шаблоны полезны и сами по себе, но в полной мере их возможности раскрываются при использовании с пользовательскими элементами. Пользовательские элементы — это тема для отдельного материала, а сейчас, для понимания происходящего, достаточно учитывать то, что API браузеров customElement позволяет программисту описывать собственные HTML-теги и задавать то, как элементы, создаваемые с помощью этих тегов, будут выглядеть на экране.
Определим веб-компонент, который использует наш шаблон в качестве содержимого для своего теневого DOM. Назовём этот новый элемент :
Самое важное, на что тут надо обратить внимание — это то, что мы присоединили клон содержимого шаблона, сделанный с помощью метода Node.cloneNode(), к теневому корню.
Так как мы присоединяем содержимое шаблона к теневому DOM, мы можем включить в шаблон некую информацию о стилизации, в элементе
Теперь описанный нами пользовательский элемент можно использовать на обычных веб-страницах следующим образом:
Слоты
Слоты можно воспринимать как местозаполнители, которые позволяют включать в шаблон собственный HTML-код. Это позволяет создавать универсальные HTML-шаблоны, а затем делать их настраиваемыми, добавляя в них слоты.
Взглянем на то, как будет выглядеть вышеописанный шаблон с использованием тега :
Как и ранее, тут может быть всё, что угодно. Например:
Элементы, которые можно помещать в слоты, называются Slotable-элементами.
После обработки вышеописанной разметки браузером будет создано следующее дерево Flattened DOM:
Стилизация
Компоненты, которые используют технологию Shadow DOM, можно стилизовать на общих основаниях, они могут определять собственные стили, или предоставлять хуки в форме пользовательских свойств CSS, которые позволяют пользователям компонентов переопределять стили, заданные по умолчанию.
▍Стили, описываемые в компонентах
Изоляция CSS — это одно из самых замечательных свойств технологии Shadow DOM. А именно, речь идёт о следующем:
▍Псевдокласс :host
Псевдокласс :host позволяет обращаться к элементу, содержащему теневое дерево DOM и стилизовать этот элемент:
Пользуясь псевдоклассом :host следует помнить о том, что правила родительской страницы имеют более высокий приоритет, чем те, которые заданы в элементе с использованием этого псевдокласса. Это позволяет пользователям переопределять стили хост-компонента, заданные в нём, извне. Кроме того, псевдокласс :host работает лишь в контексте теневого корневого элемента, за пределами теневого дерева DOM пользоваться им нельзя.
▍Темы и элементы с псевдоклассом :host-context( )
Обычный вариант использования этой возможности заключается в стилизации элементов с помощью тем. Например, часто темы применяют, назначая соответствующий класс тегам или :
Конструкция :host-context() может быть полезной для применения тем, но для этой цели лучше использовать хуки с применением пользовательских свойств CSS.
▍Стилизация хост-элемента компонента извне
Хост-элемент компонента можно стилизовать извне, используя имя его тега в качестве селектора:
Внешние стили имеют более высокий приоритет, чем стили, определённые в теневом DOM.
Предположим, пользователь создал следующий селектор:
Он переопределит правило, заданное в самом компоненте:
Используя этот подход можно стилизовать лишь сам компонент. Как стилизовать внутренние структуры компонента? Для этой цели используются пользовательские свойства CSS.
▍Создание хуков стилей с использованием пользовательских свойств CSS
Пользователи могут настраивать стили внутренних структур компонентов если автор компонента предоставляет им хуки стилей, применяя пользовательские свойства CSS.
Вот что находится внутри теневого дерева DOM:
В роли автора компонента вы ответственны за то, чтобы сообщить его пользователям о том, какие именно пользовательские CSS-свойства они могут использовать. Считайте это частью открытого интерфейса вашего компонента.
API JavaScript для работы со слотами
API Shadow DOM предоставляет возможности работы со слотами.
▍Событие slotchange
Событие slotchange вызывается при изменении узлов, помещённых в слот. Например, если пользователь добавляет дочерние узлы в Light DOM или удаляет их из него:
▍Метод assignedNodes()
Метод assignedNodes() может оказаться полезным в том случае, если нужно узнать о том, какие элементы связаны со слотом. Вызов метода slot.assignedNodes() позволяет узнать о том, какие именно элементы выводятся средствами слота. Использование опции
В первом случае мы добавляем в слот собственное содержимое:
Во втором случае мы не заполняем слот собственным содержимым:
Если, однако, передать этому методу параметр
Модель событий
Поговорим о том, что происходит при всплытии события, возникшего в теневом дереве DOM. Цель события задаётся с учётом инкапсуляции, поддерживаемой технологией Shadow DOM. Когда событие перенаправляется, это выглядит так, как будто оно исходит от самого компонента, а не от его внутреннего элемента, который находится в теневом дереве DOM и является частью этого компонента.
Вот список событий, которые передаются из теневого дерева DOM (некоторым событиям такое поведение не свойственно):
Пользовательские события
Поддержка Shadow DOM браузерами
Для того чтобы узнать, поддерживает ли браузер технологию Shadow DOM, можно проверить наличие attachShadow :
Вот сведения о поддержке этой технологии различными браузерами.
Поддержка технологии Shadow DOM в браузерах
Итоги
Практика показывает, что всё больше современных веб-приложений используют Shadow DOM, что позволяет говорить о том, что эту технологию, вероятно, ждёт дальнейшее развитие и распространение.
Уважаемые читатели! Пользуетесь ли вы веб-компонентами, построенными на основе технологии Shadow DOM?