Перейти к содержимому

Продвинутые техники DOM

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

Создание и использование шаблонов

Использование элемента <template>

Элемент <template> позволяет определять HTML-контент, который не отображается сразу при загрузке страницы. Это полезно для создания повторно используемых фрагментов HTML.


html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Using the <template> Element</title>
</head>
<body>
    <template id="my-template">
        <div class="card">
            <h2>Title</h2>
            <p>Content goes here...</p>
        </div>
    </template>
    <button id="show-template">Show Template</button>
    <div id="content"></div>

    <script>
        document.getElementById('show-template').addEventListener('click', () => {
            const template = document.getElementById('my-template');
            const content = document.getElementById('content');
            const clone = template.content.cloneNode(true);
            content.appendChild(clone);
        });
    </script>
</body>
</html>

Этот пример демонстрирует базовую структуру элемента <template>, содержащего карточку с заголовком и содержимым. Содержимое шаблона клонируется и вставляется в DOM при нажатии на кнопку.

Клонирование и вставка содержимого шаблона

Чтобы использовать содержимое <template>, его нужно клонировать и вставить в DOM.


html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Cloning and Inserting Template Content</title>
</head>
<body>
    <template id="my-template">
        <div class="card">
            <h2>Dynamic Title</h2>
            <p>Dynamic content goes here...</p>
        </div>
    </template>

    <button id="add-card">Add Card</button>
    <div id="container"></div>

    <script>
        document.getElementById('add-card').addEventListener('click', () => {
            const template = document.getElementById('my-template');
            const clone = template.content.cloneNode(true);
            document.getElementById('container').appendChild(clone);
        });
    </script>
</body>
</html>

В этом примере показано, как клонировать содержимое элемента <template> и вставить его в DOM при нажатии кнопки. В качестве альтернативы можно использовать document.importNode(template.content, true) для импорта содержимого шаблона в текущий документ перед его добавлением.

Shadow DOM

Введение в Shadow DOM

Shadow DOM — это веб-стандарт, обеспечивающий инкапсуляцию в веб-компонентах. Он позволяет скрыть внутреннюю структуру, стили и поведение компонента от глобальной области видимости документа, предотвращая конфликты стилей и скриптов.

Инкапсуляция и компонентно-ориентированная разработка

Инкапсуляция является ключевой концепцией Shadow DOM, которая гарантирует, что стили и скрипты, определенные внутри компонента, не выходят за его пределы и не влияют на остальную часть документа.


html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Shadow DOM Example</title>
    <style>
        .card {
            padding: 20px;
            margin: 10px;
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <div id="shadow-host" class="card">
        <span>This is the light DOM content</span>
    </div>

    <script>
        const host = document.getElementById('shadow-host');
        const shadowRoot = host.attachShadow({ mode: 'open' });

        const fragment = document.createDocumentFragment();
        const style = document.createElement('style');
        style.textContent = `.shadow-card { padding: 20px; margin: 10px; border: 1px solid blue; color: blue; }`;
        const slot = document.createElement('slot');
        const card = document.createElement('div');
        card.className = 'shadow-card';
        card.textContent = 'This is inside the Shadow DOM';

        fragment.appendChild(style);
        fragment.appendChild(slot);
        fragment.appendChild(card);
        shadowRoot.appendChild(fragment);
    </script>
</body>
</html>

В этом примере создается Shadow DOM для элемента #shadow-host, в который внедряются контент и стили. Контент светового DOM ("This is the light DOM content") теперь находится внутри span в пределах #shadow-host, что делает его видимым вместе с контентом Shadow DOM через элемент <slot>. Shadow DOM не перезаписывает контент светового DOM, а сосуществует с ним.

Лучшие практики

  • Предпочитайте DocumentFragment для Shadow DOM: Добавление фрагмента к корню тени за одну операцию минимизирует пересчет макета и повышает производительность рендеринга.
  • Используйте document.importNode() для шаблонов: При клонировании контента между разными документами или iframe-ами importNode обеспечивает правильное владение узлами и предотвращает ошибки кросс-документного взаимодействия.
  • Держите световой DOM минимальным: Используйте элементы <slot> для проецирования только необходимого контента, сохраняя элемент-хост чистым и предсказуемым.

INFO

Используйте Shadow DOM для инкапсуляции стилей и функциональности внутри компонентов, предотвращая конфликты стилей и обеспечивая модульный, поддерживаемый код.

Заключение

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

Практика

Какие из следующих утверждений о продвинутых техниках манипуляции с DOM являются верными?

Считаете ли это полезным?

Предпросмотр dual-run — сравните с маршрутами Symfony на продакшене.