HTML5 template: шаблоны разметки без рендера и лишнего JavaScript

HTML5 template: шаблоны разметки без рендера и лишнего JavaScript

HTML5 template: шаблоны разметки без рендера и лишнего JavaScript

Если вам нужно многократно добавлять на страницу одинаковые блоки — карточки товаров, сообщения чата, пункты списка, строки таблицы, — не обязательно собирать HTML длинными строками в JavaScript. Для этого в HTML5 есть тег <template>. Он хранит разметку в документе, но браузер не рендерит её до тех пор, пока вы сами не скопируете содержимое шаблона и не вставите его в нужное место.

Эта статья оптимизирована под запрос «HTML template пример» и показывает практический сценарий: создадим список товаров на основе HTML-шаблона.

Что делает тег template в HTML5

<template> — это контейнер для «спящей» разметки. Всё, что находится внутри него:

  • не отображается на странице;
  • не участвует в обычном потоке документа;
  • не загружает изображения как видимый контент;
  • становится доступным через свойство template.content в JavaScript.
  • Базовый пример выглядит так:

    <template id="message-template">
      <article class="message">
        <h3 class="message__title"></h3>
        <p class="message__text"></p>
      </article>
    </template>

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

    Практический пример: карточки товаров из template

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

    <section class="catalog" aria-label="Каталог товаров">
      <div class="catalog__grid" id="product-list"></div>
    </section>
    
    <template id="product-card-template">
      <article class="product-card">
        <img class="product-card__image" src="" alt="" width="300" height="200">
        <h3 class="product-card__title"></h3>
        <p class="product-card__price"></p>
        <button class="product-card__button" type="button">В корзину</button>
      </article>
    </template>

    Теперь добавим JavaScript, который берёт шаблон, клонирует его и заполняет данными.

    const products = [
      {
        title: 'HTML и CSS: стартовый набор',
        price: 990,
        image: 'images/html-css.jpg'
      },
      {
        title: 'JavaScript для верстальщика',
        price: 1490,
        image: 'images/js.jpg'
      },
      {
        title: 'Адаптивная вёрстка',
        price: 1290,
        image: 'images/adaptive.jpg'
      }
    ];
    
    const list = document.querySelector('#product-list');
    const template = document.querySelector('#product-card-template');
    
    products.forEach((product) => {
      const card = template.content.cloneNode(true);
    
      const image = card.querySelector('.product-card__image');
      const title = card.querySelector('.product-card__title');
      const price = card.querySelector('.product-card__price');
    
      image.src = product.image;
      image.alt = product.title;
      title.textContent = product.title;
      price.textContent = `${product.price} ₽`;
    
      list.append(card);
    });

    Ключевая строка здесь — template.content.cloneNode(true). Метод cloneNode(true) создаёт глубокую копию, то есть копирует не только сам контейнер, но и все вложенные элементы.

    Почему template лучше, чем сборка HTML строками

    Новички часто пишут так:

    list.innerHTML += `
      <article class="product-card">
        <h3>${product.title}</h3>
        <p>${product.price} ₽</p>
      </article>
    `;

    Такой подход кажется коротким, но у него есть минусы:

  • сложнее поддерживать большую разметку;
  • выше риск XSS, если вставлять пользовательские данные через HTML;
  • при innerHTML += браузер может пересоздавать уже существующие узлы;
  • HTML и логика смешиваются в одну нечитаемую строку.
  • С <template> структура остаётся в HTML, а JavaScript только подставляет данные. Это аккуратнее и ближе к компонентному мышлению.

    Ускоряем вставку через DocumentFragment

    Если элементов много, лучше сначала собрать их во фрагмент, а затем один раз добавить в DOM. Это снижает количество операций с реальной страницей.

    const fragment = document.createDocumentFragment();
    
    products.forEach((product) => {
      const card = template.content.cloneNode(true);
    
      card.querySelector('.product-card__title').textContent = product.title;
      card.querySelector('.product-card__price').textContent = `${product.price} ₽`;
    
      const image = card.querySelector('.product-card__image');
      image.src = product.image;
      image.alt = product.title;
    
      fragment.append(card);
    });
    
    list.append(fragment);

    Для маленьких списков разница почти незаметна, но для сотен элементов такой приём полезен.

    Обработчики событий: где их добавлять

    После клонирования шаблона можно назначить обработчик кнопке внутри карточки:

    products.forEach((product) => {
      const card = template.content.cloneNode(true);
      const button = card.querySelector('.product-card__button');
    
      card.querySelector('.product-card__title').textContent = product.title;
    
      button.addEventListener('click', () => {
        console.log(`Добавлен товар: ${product.title}`);
      });
    
      list.append(card);
    });

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

    Важные советы по использованию template

  • Не забывайте про cloneNode(true). Если передать false, вложенная разметка не скопируется.
  • Используйте textContent для текста. Это безопаснее, чем вставлять данные через innerHTML.
  • Заполняйте alt у изображений. Это важно для доступности и SEO.
  • Давайте шаблонам понятные id. Например, product-card-template, а не просто tpl1.
  • Не помещайте в шаблон критически важный видимый контент. Пока JavaScript не выполнится, пользователь его не увидит.
  • Когда использовать HTML template

    Тег <template> хорошо подходит для:

  • карточек товаров и статей;
  • сообщений в чате;
  • уведомлений;
  • строк таблицы;
  • повторяющихся блоков интерфейса;
  • простых виджетов без подключения фреймворка.
  • Если вы только осваиваете современную вёрстку и хотите уверенно понимать, где заканчивается HTML и начинается логика JavaScript, посмотрите практический курс «Вёрстка сайта с нуля 2.0»: он поможет системно прокачать базу и собирать страницы более осознанно.

    Типичные ошибки новичков

    Ошибка 1: пытаться искать элементы шаблона напрямую на странице.

    // Неправильно: элемент внутри template не находится как обычный видимый блок
    const title = document.querySelector('.product-card__title');

    Искать элементы нужно внутри клонированного фрагмента:

    const card = template.content.cloneNode(true);
    const title = card.querySelector('.product-card__title');

    Ошибка 2: вставлять пользовательский HTML без проверки. Если данные пришли от пользователя, используйте textContent, а не innerHTML.

    Ошибка 3: забывать, что template не отображается без JavaScript. Для критичного контента лучше иметь серверную разметку или fallback.

    Итог

    <template> в HTML5 — простой и полезный инструмент для повторяющейся разметки. Он помогает держать HTML отдельно от логики, безопасно подставлять данные и создавать элементы интерфейса без тяжёлых библиотек. Для новичков это отличный шаг от статичной страницы к динамическому интерфейсу, а для продолжающих разработчиков — удобный способ писать чище и поддерживаемее.

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий