Теневой DOM (Shady DOM)

d30c4a44b88e46ff87ae6922f4f3f5c7.pngНа Google I/O нам был представлен Polymer 1.0. Это новый релиз инструмента, который включает ряд особенностей и нововведении. Пожалуй начать стоит именно с Shady DOM.

Зачем нам еще один DOM? Инкапсуляция является основой веб-компонентов.

Целью веб-компонентов является предоставление пользователю простого интерфейса для отображения сложных элементов, реализация которых скрыта.Браузеры часто используют инкапсуляцию. Например элементы или 

Shadow DOM нацелен на решение данной проблемы. Браузеры которые поддерживают shadow DOM могут отображать сложные элементы скрывая реализацию (DOM, CSS, JS).

Простая размета — это хорошо!

Давайте представим элемент x-fade, суть которого заключается в красивом появлении изображения при его загрузке. И допустим мы реализовали плагин для него: $('x-fade').makeFade (); Автор будет очень доволен, так как он добьется необходимого ему поведения.По факту, это все, что нам надо от веб-компонентов — простая разметка для достижения необходимого поведения. Но подход основанный на плагине имеет ряд недостатков который решает shadow DOM.

Загрязнение DOM Допустим после вызова makefade, мы имеем следующий DOM:

Плагину x-fade необходим некоторый DOM, для достижения своей цели. Элементы которые он добавил — открыты, что ведет к следующим проблемам: Детали реализации раскрыты. Селекторы которые проходят по дереву документа будут включать и 
. Так как автор не ожидал появление этих элементов, они могут унаследовать ненужные стили. Элемент , напротив может потерять свои стили, так как он уже не является частью прежнего DOM. Может ли автор добавить новый элемент? Изменить или удалить? Как поступить если элементы уже не там где были изначально. Tree Scoping Область видимости дерева, позволяет нам скрыть часть дерева DOM, от основного документа.Если мы реализуем x-fade используя shadow DOM, то после вызова makeFade, наше дерево будет выглядеть так: То есть, абсолютно точно так же как и до инициализации.Отображение в браузере отличается от того как оно представленно в коде. Для разработчика это по прежнему элемент, в котором всего один .Благодаря данной возможности мы решили все вышеперечисленные проблемы. А именно: Детали реализации сокрыты. Выборки проходящие по документу не будут включать в себя canvas и 
. Новые элементы не будут наследовать стили не потеряет своих стилей, так как он никуда не переместился. Разработчики с легкостью может добавить новое изображение или изменить текущее. Инкапсуляция Shadow DOM Если мы решим взглянуть на полную картину того, что же мы получили, то мы увидим следующее: #shadow-root
Ага, вот и наши и 
. Так же вы могли отметить новый элемент . Это пример композиции shadow DOM с так называемым light DOM — тот, что мы можем передать элементу.В момент рендеринга эти два DOM’а объединяются и выглядят как результат работы jQuery (для браузера разумеется, мы же этого не видим):
Shadow DOM так крут, так зачем нам еще один shady DOM?! b6fb046ef53a4f30965263c2970897e5.jpgShadow DOM скрывает дерево DOM, от всего документа. Cелекторы которые мы будем делать по документу (childNodes, children, firstChild итд) не будут включать в результате скрытые элементы.

Сделать полифил для такого поведения ОЧЕНЬ сложно. Нам необходимо добиться такого же композиционного отображения DOM дерева, при этом скрыть его от логического кода.Это означает, что нам необходимо модифицировать все доступные методы по работе с элементами, что бы возвращать кастомную информацию.

Мы реализовали такой полифил, но цена:

Очень много кода. Переопределение методов, замедляет работу с элементами. Такие структуры как NodeList, нам не подвластны. Аксессоры (например window.document, window.document.body), не могут быть переопределены. Полифил возвращает проксированнные объекты, что может запутать. Большинство проектов попросту не могут быть реализованны из-за перечисленных выше недостатков, а в Safari, мы имеем ужасную производительность.

Shady DOM Аля франкенштейн который Гугл всячески пытается похвалить. Жаль, но другого выхода нет

Грубо говоря Shady DOM, предоставляет нам совместимую с shadow DOM модель области видимости дерева. В результате работы мы получим абсолютно точно такой же DOM как и при работе с jQuery плагином.

А другими словами господа, все те самые недостатки которые мы якобы побороли — открытая реализация, проблемы со стилями и остальные.Все, что смог от части сохранить Гугл, так это то, как представлено дерево в коде. Но для этого нам ОБЯЗАТЕЛЬНО, необходимо использовать новое API по работе с DOM и только тогда мы будем работать с элементами будто нечего и не произошло и видеть его так:

На самом деле в пределах элемента, это выглядит вполне себе достойно: var arrayOfNodes = Polymer.dom (x-fade).children; Таким образом мы можем работать как и с внутренним DOM так и со светлым DOM.Из полимера не была вытиснута полностью модель shadow DOM’а. Совместимость shady с shadow позволяет нам писать в одном стиле. Если хотите, вы можете сделать так, что бы полимер решал, где он может использовать shadow DOM нативно, а где включать в работу shady.

Выводы Веб-компонентам необходима инкапсуляция, ага… Shadow DOM имплементирует инкапсуляцию, но нативно его только Гугл и поддерживает. Пытаться сделать полифил для shadow DOM затея сложная и медленная в перспективе. Shady DOM представляет нам супер-быстрый аналог полифила shadow DOM’а, но с некоторыми самой большой кучей недостатков, но у нас есть новое API для вас ;) Shady DOM дает нам возможность расширить аудиторию приложений которые мы может разрабатывать используя данную модель. Все эти неудобства доказывают, что все платформы должны поддерживать shadow DOM нативно. На самом деле я очень доволен самим полимером. Как было сказано на конференции, компоненты реакта работают только в реакте, компоненты ангуляра только с ангуляром, а компоненты написанные с использование полимера — работают везде. Они занимают уровень между веб-платформой и фреймворками. Вы можете использовать их с любым фреймворком или же написать приложение используя только компоненты.У меня был опыт скрещивания Backbone с React компонентами, но это не так круто как может показаться. А вот компоненты полимера + Backbone прям конфетка.

© Habrahabr.ru