Использование шаблонов: теги <template> и <slot>
Зачем нужны шаблоны? 🤔
Когда вы создаёте много повторяющихся элементов (например, карточки товаров или комментарии), копировать один и тот же HTML-код — неэффективно. Здесь на помощь приходят теги <template> и <slot>:
<template>— контейнер для HTML-кода, который не отображается на странице, но может быть клонирован и использован в JavaScript.<slot>— заполнитель внутри шаблона, куда можно подставлять разный контент.
Как работает <template>?
Тег <template> хранит «заготовку» разметки. Браузер не обрабатывает его содержимое, пока вы не активируете шаблон через JavaScript.
<template id="user-card">
<div class="card">
<h2 class="username"></h2>
<p class="email"></p>
</div>
</template>
Использование шаблона:
- Клонируем содержимое
template. - Наполняем данными.
- Добавляем в DOM.
const template = document.getElementById('user-card');
const clone = template.content.cloneNode(true); // true = глубокое копирование
// Заполняем данные
clone.querySelector('.username').textContent = 'Данила Бежин';
clone.querySelector('.email').textContent = 'danila@example.com';
// Вставляем в документ
document.body.appendChild(clone);
Результат: На странице появится карточка пользователя без дублирования кода.
Магия <slot>: Гибкие шаблоны
<slot> позволяет создавать переиспользуемые шаблоны с динамическим содержимым.
Пример: Карточка с «дырками»
<template id="card-template">
<div class="card">
<slot name="title">Заголовок по умолчанию</slot>
<slot name="content">Текст по умолчанию</slot>
</div>
</template>
Как заполнить слоты?
Используем элемент <template> вместе с <slot> и атрибутом slot:
<div id="container"></div>
<script>
const template = document.getElementById('card-template');
const clone = template.content.cloneNode(true);
// Создаём контент для слотов
const title = document.createElement('h2');
title.textContent = 'Привет, мир!';
title.setAttribute('slot', 'title'); // Указываем имя слота
const content = document.createElement('p');
content.textContent = 'Этот текст появится в слоте content.';
content.setAttribute('slot', 'content');
// Добавляем в шаблон
clone.appendChild(title);
clone.appendChild(content);
// Вставляем в DOM
document.getElementById('container').appendChild(clone);
</script>
Что произойдёт:
- <h2> с текстом «Привет, мир!» займёт место <slot name="title">.
- <p> с текстом появится вместо <slot name="content">.
Комбинируем с Shadow DOM 🌑
Шаблоны особенно мощны в сочетании с Shadow DOM (изолированным DOM-поддеревом).
class UserCard extends HTMLElement {
constructor() {
super();
// Создаём Shadow DOM
const shadow = this.attachShadow({ mode: 'open' });
// Клонируем шаблон
const template = document.getElementById('user-card-template');
const clone = template.content.cloneNode(true);
// Добавляем в Shadow DOM
shadow.appendChild(clone);
}
}
// Регистрируем кастомный элемент
customElements.define('user-card', UserCard);
Теперь можно использовать <user-card></user-card> в HTML, и браузер автоматически подставит шаблон!
Практика: Делаем «живые» компоненты
Задача: Создать шаблон кнопки с изменяемым текстом и стилями.
<template id="fancy-button">
<style>
button {
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
}
</style>
<button>
<slot>Кнопка</slot>
</button>
</template>
<!-- Использование -->
<fancy-button>Нажми меня!</fancy-button>
<script>
class FancyButton extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const template = document.getElementById('fancy-button');
shadow.appendChild(template.content.cloneNode(true));
}
}
customElements.define('fancy-button', FancyButton);
</script>
Итог:
- Текст внутри <fancy-button> автоматически попадает в <slot>.
- Стили изолированы в Shadow DOM.
Итоги 🏁
<template>+ JavaScript = переиспользуемые блоки HTML.<slot>= динамические «дырки» в шаблоне.- Shadow DOM + шаблоны = изолированные компоненты.
Попробуйте создать свой компонент — например, карточку профиля или модальное окно!