strokoff

Декларативный shadow DOM

Декларативный shadow DOM

Мы рады сообщить, что поддержка декларативного теневого API DOM была добавлена ​​и включена по умолчанию в Safari Technology Preview 162 . Напомним, теневой DOM является частью веб-компонентов, набора спецификаций, которые изначально были предложены Google для создания многоразовых виджетов и компонентов в Интернете. С тех пор эти спецификации были интегрированы в стандарты DOM и HTML. Shadow DOM , в частности, обеспечивает облегченную инкапсуляцию для деревьев DOM, позволяя создавать параллельное дерево для элемента, называемого «теневым деревом», которое заменяет рендеринг элемента без изменения собственного дерева DOM.

До этого момента для создания теневого дерева для элемента требовался вызов attachShadow() этого элемента в JavaScript. Это означало, что эта функция была недоступна, когда JavaScript отключен, например, в почтовых клиентах, и требовалось скрыть содержимое, которое должно было находиться в теневом дереве, до тех пор, пока не будут загружены соответствующие сценарии, чтобы избежать сброса содержимого. Кроме того, многие современные веб-сайты и веб-приложения используют метод, называемый «SSR — рендеринг на стороне сервера », при котором программы, работающие на веб-сервере, генерируют HTML-разметку с начальным содержимым для использования веб-браузерами, вместо того, чтобы получать содержимое по сети после того, как сценарии загружены. Это помогает сократить время загрузки страницы, а также улучшает SEO .потому что содержимое страницы легко доступно для поисковых роботов. Многие технологии рендеринга на стороне сервера пытаются устранить необходимость в JavaScript для начального рендеринга, чтобы уменьшить начальную задержку отрисовки и постепенно улучшать контент за счет интерактивности по мере загрузки сценариев и связанных метаданных. К сожалению, это было невозможно при использовании теневого DOM из-за вышеупомянутого требования использовать attachShadow().

Декларативный теневой DOM решает эти варианты использования, предоставляя механизм для включения содержимого теневого DOM в HTML. В частности, указание shadowrootmode атрибута содержимого для template элемента сообщает веб-браузерам, что содержимое внутри этого template элемента должно быть помещено в теневой DOM, прикрепленное к его родительскому элементу. Например, в следующем примере элемент templateс shadowrootmode прикрепит теневой root element к some-component элементу с текстовым узлом, содержащим «привет, мир». как его единственный дочерний узел,

<some-component>
    <template shadowrootmode="closed">hello, world.</template>
</some-component>

Когда сценарии загружены и готовы сделать этот контент интерактивным, доступ к теневому корню ElementInternals можно получить следующим образом:

customElements.define('some-component', class SomeComponent extends HTMLElement {
    #internals;
    constructor() {
        super();
        this.#internals = this.attachInternals();

        // This will log "hello, world."
        console.log(this.#internals.shadowRoot.textContent.trim());
    }
});

API разработан с учетом обратной совместимости. Например, вызов attachShadow() элемента с декларативной теневой моделью DOM возвращает декларативно присоединенный теневой root element со всеми удаленными дочерними элементами, а не завершается ошибкой, вызывая исключение. Это означает, что принятие декларативного теневого DOM обратно совместимо с существующим JavaScript, который полагается на attachShadow() создание теневых корней. Обратите внимание, что ни один из API-интерфейсов синтаксического анализатора JavaScript (например, DOMParser и innerHTML) не поддерживает декларативный теневой DOM по умолчанию, чтобы избежать создания новых уязвимостей межсайтового скриптинга на существующих веб-сайтах, которые принимают произвольное содержимое шаблона (поскольку script элементы в таком содержимом ранее были инертными и не запускались). ).

Кроме того, мы представляем возможность клонирования теневых корневых элементов. До сих пор ShadowRoot и его узлы-потомки не могли быть клонированы с помощью cloneNode() или importNode(). attachShadow() теперь принимает cloneable флаг в качестве опции. Когда для этого флага установлено значение true, существующий API JavaScript, такой как cloneNode() и , importNode() будет клонироваться ShadowRoot при клонировании своего теневого хоста. Декларативный теневой DOM автоматически устанавливает этот флаг в значение true, чтобы декларативный теневой DOM, который появляется внутри других template элементов, мог быть клонирован вместе с его родителем. В следующем примере внешний элемент шаблона содержит экземпляр some-componentelement, а содержимое его теневого дерева сериализовано с использованием декларативного теневого DOM. Клонирование template1.content с помощью document.importNode(template1.content, true) будет клонировать some-component, а также его (декларативно определенное) теневое дерево.

<template id="template1">
    <some-component>
        <template shadowrootmode="closed">hello, world.</template>
    </some-component>
</template>

Таким образом, декларативный теневой DOM представляет новый способ определения теневого дерева в HTML, который будет полезен для рендеринга веб-компонентов на стороне сервера, а также в контексте, где JavaScript отключен, например, в почтовых клиентах. Это очень востребованная функция, о которой много говорят производители браузеров. Мы рады сообщить о его появлении в Safari Technology Preview 162 .

Оригинал статьи — Declarative Shadow Dom