Web Components - Shadow DOM

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

Shadow DOM

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

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

<style>
/* Глобальные стили не влияют на Shadow DOM */
p { color: red; }
</style>

<custom-card></custom-card>
<custom-card></custom-card>

<script>
class CustomCard extends HTMLElement {
    constructor() {
        super();
        
        // Создание Shadow DOM
        const shadow = this.attachShadow({mode: "open"});
        
        // Создание содержимого
        const wrapper = document.createElement("div");
        wrapper.setAttribute("class", "card");
        
        const title = document.createElement("h3");
        title.textContent = this.getAttribute("title") || "Заголовок карточки";
        
        const content = document.createElement("div");
        content.innerHTML = `
            <p>Это содержимое карточки</p>
            <slot name="content">Контент по умолчанию</slot>
        `;
        
        // Стили для Shadow DOM
        const style = document.createElement("style");
        style.textContent = `
            .card {
                border: 2px solid #333;
                border-radius: 8px;
                padding: 16px;
                margin: 10px;
                background: white;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }
            
            h3 {
                color: #2c3e50;
                margin-top: 0;
                border-bottom: 1px solid #eee;
                padding-bottom: 8px;
            }
            
            p {
                color: #7f8c8d; /* Этот стиль переопределит глобальный */
                line-height: 1.5;
            }
        `;
        
        // Добавление элементов в Shadow DOM
        wrapper.appendChild(title);
        wrapper.appendChild(content);
        shadow.appendChild(style);
        shadow.appendChild(wrapper);
    }
}

// Регистрация компонента
customElements.define("custom-card", CustomCard);

// Динамическое создание карточек
setTimeout(() => {
    const card = document.createElement("custom-card");
    card.setAttribute("title", "Динамическая карточка");
    document.body.appendChild(card);
}, 2000);
</script>

<custom-card title="Особая карточка">
    <span slot="content">
        Это специальный контент для карточки!
    </span>
</custom-card>