Shadow root closed что это

Shadow DOM

Теневой DOM («Shadow DOM») используется для инкапсуляции. Благодаря ему в компоненте есть собственное «теневое» DOM-дерево, к которому нельзя просто так обратиться из главного документа, у него могут быть изолированные CSS-правила и т.д.

Встроенный теневой DOM

Задумывались ли вы о том, как устроены и стилизованы сложные браузерные элементы управления?

Браузер рисует их своими силами и по своему усмотрению. Их DOM-структура обычно нам не видна, но в инструментах разработчика можно её посмотреть. К примеру, в Chrome для этого нужно активировать пункт «Show user agent shadow DOM».

После этого выглядит так:

Shadow root closed что это. shadow dom range. Shadow root closed что это фото. Shadow root closed что это-shadow dom range. картинка Shadow root closed что это. картинка shadow dom range

То, что находится под #shadow-root – и называется «shadow DOM» (теневой DOM).

Мы не можем получить доступ к теневому DOM встроенных элементов с помощью обычных JavaScript-вызовов или с помощью селекторов. Это не просто обычные потомки, это мощное средство инкапсуляции.

Ещё раз заметим, что pseudo – нестандартный атрибут. Если говорить хронологически, то сначала браузеры начали экспериментировать с инкапсуляцией внутренних DOM-структур для элементов, а уже потом, через некоторое время, появился стандарт Shadow DOM, который позволяет делать то же самое нам, разработчикам.

Далее мы воспользуемся современным стандартом Shadow DOM, описанным в спецификации DOM spec и других спецификациях.

Теневое дерево

Каждый DOM-элемент может иметь 2 типа поддеревьев DOM:

Если у элемента имеются оба поддерева, браузер отрисовывает только теневое дерево. Также мы всё же можем задать «композицию» теневого и обычного деревьев. Позже в главе Слоты теневого DOM, композиция мы рассмотрим детали.

Теневое дерево можно использовать в пользовательских элементах (Custom Elements), чтобы спрятать внутренности компонента и применить к ним локальные стили.

Например, этот элемент прячет свой внутренний DOM в теневом дереве:

А вот как получившийся DOM выглядит в инструментах разработчика в Chrome, весь контент внутри «#shadow-root»:

Shadow root closed что это. shadow dom say hello. Shadow root closed что это фото. Shadow root closed что это-shadow dom say hello. картинка Shadow root closed что это. картинка shadow dom say hello

Итак, вызов elem.attachShadow() создаёт теневое дерево.

Есть два ограничения:

Свойство mode задаёт уровень инкапсуляции. У него может быть только два значения:

Элемент с корнем теневого дерева называется – «хозяин» (host) теневого дерева, и он доступен в качестве свойства host у shadow root:

Инкапсуляция

Теневой DOM отделён от главного документа:

Ссылки

Итого

Теневой DOM – это способ создать свой, изолированный, DOM для компонента.

Элементы теневого DOM:

Теневой DOM, если имеется, отрисовывается браузером вместо обычных потомков (light DOM). В главе Слоты теневого DOM, композиция мы разберём, как делать их композицию.

Источник

Как работает JS: технология Shadow DOM и веб-компоненты

Сегодня, в переводе 17 части материалов, посвящённых особенностям всего, что так или иначе связано с JavaScript, речь пойдёт о веб-компонентах и о различных стандартах, которые направлены на работу с ними. Особое внимание здесь будет уделено технологии Shadow DOM.

Shadow root closed что это. image loader. Shadow root closed что это фото. Shadow root closed что это-image loader. картинка Shadow root closed что это. картинка image loader

Обзор

Веб-компоненты — это семейство API, предназначенных для описания новых элементов DOM, подходящих для повторного использования. Функционал таких элементов отделён от остального кода, их можно применять в веб-приложениях собственной разработки.

Существует четыре технологии, относящиеся к веб-компонентам:

Технология Shadow DOM

Тут предполагается, что вы уже знакомы с концепцией DOM и с соответствующими API. Если это не так — можете почитать этот материал.

Shadow DOM — это, в целом, то же самое, что и обычный DOM, но с двумя отличиями:

Это изолированное поддерево называют shadow tree (теневое дерево). Элемент, к которому присоединено такое дерево, называется shadow host (теневой хост-элемент). Всё, что добавляется в теневое поддерево DOM, оказывается локальным для элемента, к которому оно присоединено, в том числе — стили, описываемые с помощью тегов Shadow root closed что это. boot. Shadow root closed что это фото. Shadow root closed что это-boot. картинка Shadow root closed что это. картинка bootLaunch

Шаблоны

Если включить такую конструкцию в состав HTML-разметки страницы, содержимое описываемого ей тега

не появится на экране до тех пор, пока не будет явным образом присоединено к DOM документа. Например, это может выглядеть так:

Существуют и другие средства, позволяющие достичь того же эффекта, но, как уже было сказано, шаблоны — очень удобный стандартный инструмент, пользующийся хорошей поддержкой браузеров.

Shadow root closed что это. image loader. Shadow root closed что это фото. Shadow root closed что это-image loader. картинка Shadow root closed что это. картинка image loader

Поддержка 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 root closed что это. image loader. Shadow root closed что это фото. Shadow root closed что это-image loader. картинка Shadow root closed что это. картинка image loader

Поддержка технологии Shadow DOM в браузерах

Итоги

Практика показывает, что всё больше современных веб-приложений используют Shadow DOM, что позволяет говорить о том, что эту технологию, вероятно, ждёт дальнейшее развитие и распространение.

Уважаемые читатели! Пользуетесь ли вы веб-компонентами, построенными на основе технологии Shadow DOM?

Источник

Using shadow DOM

An important aspect of web components is encapsulation — being able to keep the markup structure, style, and behavior hidden and separate from other code on the page so that different parts do not clash, and the code can be kept nice and clean. The Shadow DOM API is a key part of this, providing a way to attach a hidden separated DOM to an element. This article covers the basics of using the Shadow DOM.

Note: Shadow DOM is supported by default in Firefox (63 and onwards), Chrome, Opera, and Safari. The new Chromium-based Edge (79 and onwards) supports it too; the old Edge didn’t.

High-level view

This article assumes you are already familiar with the concept of the DOM (Document Object Model) — a tree-like structure of connected nodes that represents the different elements and strings of text appearing in a markup document (usually an HTML document in the case of web documents). As an example, consider the following HTML fragment:

This fragment produces the following DOM structure:

Shadow root closed что это. dom screenshot. Shadow root closed что это фото. Shadow root closed что это-dom screenshot. картинка Shadow root closed что это. картинка dom screenshot

Shadow DOM allows hidden DOM trees to be attached to elements in the regular DOM tree — this shadow DOM tree starts with a shadow root, underneath which can be attached to any elements you want, in the same way as the normal DOM.

Shadow root closed что это. shadowdom. Shadow root closed что это фото. Shadow root closed что это-shadowdom. картинка Shadow root closed что это. картинка shadowdom

There are some bits of shadow DOM terminology to be aware of:

You can affect the nodes in the shadow DOM in exactly the same way as non-shadow nodes — for example appending children or setting attributes, styling individual nodes using element.style.foo, or adding style to the entire shadow DOM tree inside a element. The difference is that none of the code inside a shadow DOM can affect anything outside it, allowing for handy encapsulation.

Note that the shadow DOM is not a new thing by any means — browsers have used it for a long time to encapsulate the inner structure of an element. Think for example of a element, with the default browser controls exposed. All you see in the DOM is the element, but it contains a series of buttons and other controls inside its shadow DOM. The shadow DOM spec has made it so that you are allowed to actually manipulate the shadow DOM of your own custom elements.

Basic usage

You can attach a shadow root to any element using the Element.attachShadow() method. This takes as its parameter an options object that contains one option — mode — with a value of open or closed :

open means that you can access the shadow DOM using JavaScript written in the main page context, for example using the Element.shadowRoot property:

Note: As this blog post shows, it is actually fairly easy to work around closed shadow DOMs, and the hassle to completely hide them is often more than it’s worth.

If you are attaching a shadow DOM to a custom element as part of its constructor (by far the most useful application of the shadow DOM), you would use something like this:

When you’ve attached a shadow DOM to an element, manipulating it is a matter of just using the same DOM APIs as you use for the regular DOM manipulation:

Working through a simple example

Now let’s walk through a simple example to demonstrate the shadow DOM in action inside a custom element —

Inside the class definition we define the element’s constructor, which defines all the functionality the element will have when an instance of it is instantiated.

Creating the shadow root

We first attach a shadow root to the custom element:

Creating the shadow DOM structure

Next, we use some DOM manipulation to create the element’s internal shadow DOM structure:

Styling the shadow DOM

After that we create a element and populate it with some CSS to style it:

Attaching the shadow DOM to the shadow root

The final step is to attach all the created elements to the shadow root:

Using our custom element

Once the class is defined, using the element is as simple as defining it, and putting it on the page, as explained in Using custom elements:

Internal versus external styles

In the above example we apply style to the Shadow DOM using a element, but it is perfectly possible to do it by referencing an external stylesheet from a element instead.

For example, take a look at this code from our popup-info-box-external-stylesheet example (see the source code):

Many modern browsers implement an optimization for tags either cloned from a common node or that have identical text, to allow them to share a single backing stylesheet. With this optimization the performance of external and internal styles should be similar.

Источник

Веб-компоненты. Часть 2: теневой DOM

Вступление

Приветствую, коллеги, и представляю вашему вниманию продолжение серии статей о веб-компонентах, первая часть которой доступна вот тут

В этой статье речь пойдет о спецификации теневого DOM (shadow DOM) версии от 01.03.2018 г.. Последний черновик спецификации датирован 08.03.2018г.

АПИ теневого DOM позволяет нам инкапсулировать содержимое страницы, посредством помещения разметки в древовидную структуру, называемую shadow tree, которая, хотя и будет внедрена в DOM, не будет ее полноправной частью в привычном нам контексте: ее нельзя получить для взаимодействия стандартными методами js для работы с обычными потомками в DOM. Именно это АПИ в разрезе всех АПИ для создания веб-компонентов, дает нам возможность не только скрывать внутреннюю реализацию компонентов, но и инкапсулировать стили с минимальными усилиями.

Теневой DOM уже используется браузерами для внутренней реализации работы ряда элементов. Так например

при рассмотрении в консоли оказывается не единичным элементом, а именно древовидной структурой обычных HTML элементов в теневом DOM.

Основные понятия

Ключевым понятием в концепции теневого DOM является shadow tree, то самое «поддерево», которое рендерится в документ, но не находится в DOM дереве. Мне проще всего было рассматривать shadow tree как нечто среднее между частью документа и фрагметом (document fragment).

Дерево, которому принадлежит shadow root называют light tree, и, кстати light tree вполне может быть другим shadow tree.

Shadow tree может содержать элементы слоты (slot).Этот элемент — аналог documentFragment — при его рендеринге в DOM, слот заменяется на его содержимое.

Частные случаи работы элемента slot различаются в зависимости от того, задано ли значение в его атрибут name.

Если значение атрибута name задано

Когда атрибутe name элемента slot присвоено значение, то элемент slot при рендеринге документа будет заменен на те элементы документа (light tree), у которых есть атрибут slot, установленный в значение равное значению атрибута name у элемента slot.

В качестве примера я взяла код пользовательского элемента таб, составленный при написании предыдущей статьи и внесла в него следующие изменения:

В конструкторе создан и прикреплен теневой DOM. Теперь доступ к shadow root будет возможен через обращение this.shadowRoot.

Теперь в разметке при использовании пользовательского элемента я смогу задавать внутреннее содержимое элемента навигации с единственным условием, вложенные элементы должны иметь атрибут slot равный значению атрибута name у элемента slot в теневом DOM (в нашем примере — «nav»), иначе они не будут отображаться.

Аналогичные изменения я внесу в класс TabContentItem:

В связи с подключением теневого DOM необходимость в использовании атрибута content для отображения содержимого таб отпала.

Использование таких пользовательских элементов выглядит так:

Из этого примера видно, что пользователь компонента способен передать любую разметку как внутрь элемента навигации, так и внутрь элемента содержимого табы, но, повторюсь, с ограничением в виде обязательного наличия у элементов такой разметки атрибута slot (и в нашем случае — с одним и тем же значением для каждого из пользовательских элементов). На мой взгляд, это тот случай, когда второй вариант поведения элемента slot предпочительнее, а именно:

Если значение атрибута name не задано

Если имя на элементе slot не задано, то, по умолчанию, оно равно пустой строке и такой слот будут называть default slot. При рендеринге, он будет заменен на те элементы, которые не имеют атрибута slot.

Потому я уберу из разметки, задаваемой в методах render, атрибут name и его значение, а из разметки в основном документе атрибуты slot и их значения. Таким образом, вся разметка, указываемая между двумя тегами пользовательского элемента будет внедрена в дефолтный слот. Код изоляции разметки можно посмотреть вот тут.

Стили

Стили, указанные внутри тега style элемента из теневого DOM будут им ограничены. CSS селекторы из внешнего окружения не будут применяться к содержимому теневого DOM, а его стили, соответственно, не вытекут наружу, что позволяет нам использовать простейшие селекторы, которые, кроме удобства написания также лучше по производительности.

Пользовательские веб-компоненты могут стилизовать сами себя из контекста теневого DOM, используя селектор :host. При этом, правила такого селектора могут быть переписаны внешними стилями компоненты, что позволит менять стили при использовании компоненты (адаптировать при необходимости в момент использования). А :host(selector) позволяет компоненте стилизовать хост при его совпадении с селектором, что как раз используется для визуализации действий пользователя и состояния приложения. Также доступна стилизация по контексту :host-context(selector) который совпадает с компонентой только когда какой-то из предков компоненты совпадает с селектором (используется для стилизации обусловленной окружением).

Для использования из теневого DOM также доступен псевдоэлемент ::slotted(selector), который должен выбирать элементы вложенного верхнего элемента, совпадающего с селектором. О других возможностях CSS в теневом DOM можно почитать тут.

О событиях

Мой пример с табами не лучшим образом подходит для демонстрации этого, но теневой DOM имеет также особенность поведения событий. Так, например, вот список событий, которые, согласно документации, должны будут всегда останавливаться на самом внутреннем shadow root: abort, error, select, change, load, reset, resize, scrol, selectstart. А click, dbclick и почти все остальные мышиные события, wheel, blur, focus, focusin, focusout, keydown, keyup, все события перетаскивания (drag events) и некоторые другие свободно пересекают границу shadow DOM. Мне не доводилось это использовать, но я считаю что эта информация может пригодится.

О поддержке

В настоящее время поддержка первой версии спецификации реализована в Chrome, в Opera, частично в Safari и имплементируется в Firefox.

Спасибо за внимание, прошу не судить строго. С уважением Tania_N

Источник

Введение в 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.

Shadow root closed что это. settings tab chrome. Shadow root closed что это фото. Shadow root closed что это-settings tab chrome. картинка Shadow root closed что это. картинка settings tab chromeShadow root closed что это. settings tab chrome. Shadow root closed что это фото. Shadow root closed что это-settings tab chrome. картинка Shadow root closed что это. картинка settings tab chrome Shadow root closed что это. settings tab chrome. Shadow root closed что это фото. Shadow root closed что это-settings tab chrome. картинка Shadow root closed что это. картинка settings tab chrome

Теперь, когда мы активировали его в нашем браузере, давайте ознакомимся с внутренним устройством аудиоплеера по умолчанию. Просто введите:

в вашу HTML-разметку. Благодаря нему показывается следующий нативный аудиоплеер в браузерах, что его поддерживают:

Shadow root closed что это. audio player. Shadow root closed что это фото. Shadow root closed что это-audio player. картинка Shadow root closed что это. картинка audio player

Теперь давайте, проинспектируйте этот виджет аудиоплеера, который только что создали. Вау!

Shadow root closed что это. audio shadow dom. Shadow root closed что это фото. Shadow root closed что это-audio shadow dom. картинка Shadow root closed что это. картинка audio shadow domShadow root closed что это. audio shadow dom. Shadow root closed что это фото. Shadow root closed что это-audio shadow dom. картинка Shadow root closed что это. картинка audio shadow dom Shadow root closed что это. audio shadow dom. Shadow root closed что это фото. Shadow root closed что это-audio shadow dom. картинка Shadow root closed что это. картинка audio shadow dom

В инспекторе показывается внутренняя организация аудиоплеера, которую без активации показа Shadow DOM было скрыто. Как мы видим в элементе audio используется фрагмент документа для размещения внутреннего контента виджета и его добавления в элемент-контейнер (известный как Shadow Host).

Shadow Host и Shadow Root

Shadow root closed что это. sd composition1. Shadow root closed что это фото. Shadow root closed что это-sd composition1. картинка Shadow root closed что это. картинка sd composition1Shadow root closed что это. sd composition1. Shadow root closed что это фото. Shadow root closed что это-sd composition1. картинка Shadow root closed что это. картинка sd composition1 Shadow root closed что это. sd composition1. Shadow root closed что это фото. Shadow root closed что это-sd composition1. картинка Shadow root closed что это. картинка sd composition1

После выполнения кода для добавления Shadow DOM дерево Shadow заменяет контент Shadow Host.

Shadow root closed что это. sd composition2. Shadow root closed что это фото. Shadow root closed что это-sd composition2. картинка Shadow root closed что это. картинка sd composition2Shadow root closed что это. sd composition2. Shadow root closed что это фото. Shadow root closed что это-sd composition2. картинка Shadow root closed что это. картинка sd composition2 Shadow root closed что это. sd composition2. Shadow root closed что это фото. Shadow root closed что это-sd composition2. картинка Shadow root closed что это. картинка sd composition2

Этот процесс перекрытия узлов часто называют композицией (* в ООП – метод создания нового объекта путём объединения старых и новых частей, в противоположность наследованию).

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 отображается в браузере.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *