Web Components - Templates

Сложность: Продвинутый

HTML Templates

Создание переиспользуемых шаблонов для компонентов.

Пример использования:

<!-- Определение шаблонов -->
<template id="user-profile">
    <style>
        .profile {
            display: flex;
            align-items: center;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 8px;
            margin: 10px 0;
            background: #f9f9f9;
        }
        
        .avatar {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            margin-right: 15px;
            background: #3498db;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-weight: bold;
        }
        
        .info h3 {
            margin: 0 0 5px 0;
            color: #2c3e50;
        }
        
        .info p {
            margin: 0;
            color: #7f8c8d;
        }
    </style>
    
    <div class="profile">
        <div class="avatar">
            <slot name="avatar">AV</slot>
        </div>
        <div class="info">
            <h3><slot name="name">Имя пользователя</slot></h3>
            <p><slot name="role">Роль</slot></p>
            <p><slot name="email">email@example.com</slot></p>
        </div>
    </div>
</template>

<template id="product-card">
    <style>
        .product-card {
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            padding: 16px;
            margin: 10px;
            text-align: center;
            transition: transform 0.2s, box-shadow 0.2s;
        }
        
        .product-card:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
        }
        
        .product-image {
            width: 100%;
            height: 200px;
            background: #f5f5f5;
            margin-bottom: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 48px;
        }
        
        .price {
            font-size: 1.5em;
            color: #e74c3c;
            font-weight: bold;
            margin: 10px 0;
        }
        
        .add-to-cart {
            background: #3498db;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 4px;
            cursor: pointer;
            width: 100%;
        }
    </style>
    
    <div class="product-card">
        <div class="product-image">
            <slot name="image">?️</slot>
        </div>
        <h3><slot name="title">Название товара</slot></h3>
        <p><slot name="description">Описание товара</slot></p>
        <div class="price"><slot name="price">0 руб.</slot></div>
        <button class="add-to-cart" onclick="addToCart(this)">
            Добавить в корзину
        </button>
    </div>
</template>

<!-- Использование шаблонов -->
<div id="profiles-container"></div>
<div id="products-container"></div>

<script>
// Функция для создания профилей из шаблона
function createUserProfile(user) {
    const template = document.getElementById("user-profile");
    const clone = template.content.cloneNode(true);
    
    // Заполнение данными
    const avatarSlot = clone.querySelector("slot[name=\"avatar\"]");
    const nameSlot = clone.querySelector("slot[name=\"name\"]");
    const roleSlot = clone.querySelector("slot[name=\"role\"]");
    const emailSlot = clone.querySelector("slot[name=\"email\"]");
    
    avatarSlot.textContent = user.avatar;
    nameSlot.textContent = user.name;
    roleSlot.textContent = user.role;
    emailSlot.textContent = user.email;
    
    return clone;
}

// Функция для создания карточек товаров
function createProductCard(product) {
    const template = document.getElementById("product-card");
    const clone = template.content.cloneNode(true);
    
    const titleSlot = clone.querySelector("slot[name=\"title\"]");
    const descSlot = clone.querySelector("slot[name=\"description\"]");
    const priceSlot = clone.querySelector("slot[name=\"price\"]");
    const imageSlot = clone.querySelector("slot[name=\"image\"]");
    
    titleSlot.textContent = product.title;
    descSlot.textContent = product.description;
    priceSlot.textContent = `${product.price} руб.`;
    imageSlot.textContent = product.image;
    
    return clone;
}

// Данные для демонстрации
const users = [
    { avatar: "AI", name: "Алексей Иванов", role: "Разработчик", email: "alex@example.com" },
    { avatar: "MP", name: "Мария Петрова", role: "Дизайнер", email: "maria@example.com" }
];

const products = [
    { title: "Ноутбук", description: "Мощный ноутбук для работы", price: 50000, image: "?" },
    { title: "Смартфон", description: "Новейший смартфон", price: 30000, image: "?" },
    { title: "Наушники", description: "Беспроводные наушники", price: 5000, image: "?" }
];

// Добавление элементов на страницу
const profilesContainer = document.getElementById("profiles-container");
const productsContainer = document.getElementById("products-container");

users.forEach(user => {
    profilesContainer.appendChild(createUserProfile(user));
});

products.forEach(product => {
    productsContainer.appendChild(createProductCard(product));
});

// Функция для кнопки "Добавить в корзину"
function addToCart(button) {
    const productCard = button.closest(".product-card");
    const productName = productCard.querySelector("h3").textContent;
    alert(`Товар "${productName}" добавлен в корзину!`);
}
</script>