Shadow DOM е уеб стандарт, който позволява капсулиране и обхват на стилове и маркиране в конкретен компонент или елемент, като го изолира от останалата част от страницата. Той позволява създаването на многократно използвани уеб компоненти със собствено DOM дърво, CSS стилове и поведение на JavaScript. Капсулираните елементи и стилове в сенчестия DOM са скрити от основния документ, предотвратявайки намеса от външни стилове и скриптове.
т.е.: Да кажем, че създавам персонализиран компонент на бутон, наречен „my-button“. Като използвате DOM в сянка, можете да дефинирате HTML структурата на бутона, CSS стиловете и JavaScript функционалността в неговия собствен капсулиран обхват. Стиловете на компонента няма да бъдат повлияни от глобалните стилове на страницата, което гарантира последователен външен вид и поведение. След това други разработчици могат да използват вашия компонент „my-button“, без да се притесняват от конфликти с техния съществуващ CSS или JavaScript код.
export default function App() { useEffect(() => { const parentDiv = document.createElement("div"); const shadowRoot = parentDiv.attachShadow({ mode: "open" }); shadowRoot.innerHTML= `<button id="withShadow">Shadow Button</button>`; const buttonStyles = ` #withShadow { background-color: green; color: yellow; border: none; cursor: pointer; } `; const style = document.createElement('style'); style.textContent = buttonStyles; shadowRoot.appendChild(style); document.body.appendChild(parentDiv); }, []); return ( <> <button>Normal Button </button> </> ); }
В изображението можете да видите два бутона, единият е бутон без shadow dom, а другият е с активиран shadow dom.
Приложих някакъв стил върху бутона в shadow dom, но това не оказва влияние върху стила на цялостния потребителски интерфейс.
Защо се използва Shadow DOM?
По принцип отговорът е същият като по-горе.
Shadow DOM се използва за капсулиране на стиловете, структурата и поведението на уеб компонент, като се гарантира, че той няма да пречи или да бъде засегнат от стиловете и скриптовете на околна страница. Той позволява на разработчиците да създават самостоятелни компоненти със собствено DOM дърво, CSS стилове и JavaScript логика, което ги прави многократно използвани и изолирани. Това капсулиране подобрява модулността, намалява конфликтите и подобрява поддръжката на кода, което води до по-стабилни и мащабируеми уеб приложения.
Какви са различните режими в Shadow DOM?
Има три различни режима в Shadow DOM:
- Отворен режим: Този режим позволява стиловете и елементите в рамките на Shadow DOM да бъдат достъпвани и манипулирани извън компонента.
- Затворен режим: В този режим Shadow DOM е напълно капсулиран, предотвратявайки всякакъв директен достъп или манипулиране извън компонента. Стиловете и елементите остават изолирани.
- Режим на сянка: Този режим е подобен на затворения режим, но също така скрива съществуването на Shadow DOM. Стиловете и елементите са скрити, осигурявайки пълно капсулиране и поверителност.
Тези режими осигуряват гъвкавост при контролиране на достъпността и видимостта на Shadow DOM, в зависимост от изискванията на уеб компонента.
Какви са предимствата на Shadow DOM?
Има много предимства от използването на shadow DOM, но ще спомена няколко, които изпитах на практика.
- Енкапсулиране: Shadow DOM ни позволява да капсулираме стиловете, структурата и поведението на уеб компонент, като го предпазваме от намеса или влияние от стиловете и скриптовете на околната страница.
- Модулност: Със Shadow DOM компонентите се превръщат в самостоятелни обекти, които могат да се използват повторно в различни части на уеб приложение, насърчавайки модулността и повторната употреба на кода.
- Изолация: Капсулирането, предоставено от Shadow DOM, изолира компонентите от останалата част от страницата, намалявайки конфликтите и улеснявайки управлението и поддръжката на сложни уеб приложения.
- Обхват на стила: Shadow DOM гарантира, че CSS стиловете, дефинирани в компонент, се прилагат само към елементите в компонента, като се избягват непреднамерени изтичания на стилове и сблъсъци с други части на страницата.
- Подобрена производителност: Shadow DOM оптимизира производителността на рендиране, като позволява на браузъра да прави ефективни актуализации в рамките на капсулираните компоненти, свеждайки до минимум нуждата от глобални прерисовки и преформатиране.
Как може да се използва стилизиране в Shadow DOM?
Намерих четири начина за оформяне на shadow dom.
1. Вътрешен стил:
const shadowRoot = element.attachShadow({ mode: 'open' }); shadowRoot.innerHTML = ` <style> /* CSS rules specific to the Shadow DOM */ h1 { color: red; } </style> <h1>Hello, Shadow DOM!</h1> `;
В този пример стиловете са дефинирани в тага <style>
в Shadow DOM. Тези стилове ще се прилагат само към елементите в Shadow DOM.
2. Външни таблици със стилове:
const shadowRoot = element.attachShadow({ mode: 'open' }); const linkElem = document.createElement('link'); linkElem.setAttribute('rel', 'stylesheet'); linkElem.setAttribute('href', 'styles.css'); shadowRoot.appendChild(linkElem); shadowRoot.innerHTML = ` <h1>Hello, Shadow DOM!</h1> `;
Тук външен лист със стилове (styles.css) е свързан към Shadow DOM с помощта на елемент <link>
. Стиловете, дефинирани във външния стилов лист, ще бъдат приложени към елементите в рамките на Shadow DOM.
3. CSS персонализирани свойства:
const shadowRoot = element.attachShadow({ mode: 'open' }); shadowRoot.innerHTML = ` <style> /* CSS rules using custom properties */ h1 { color: var(--text-color, red); } </style> <h1>Hello, Shadow DOM!</h1> `;
Персонализираните CSS свойства могат да се използват в рамките на Shadow DOM за дефиниране на гъвкави и тематични стилове. В този пример цветът на елемента <h1>
се задава с помощта на персонализираното свойство --text-color
.
4. Използване на обекта CSSStyleSheet
const shadowRoot = element.attachShadow({ mode: 'open' }); const stylesheet = new CSSStyleSheet(); stylesheet.replaceSync(` h1 { color: red; } `); shadowRoot.adoptedStyleSheets = [stylesheet]; shadowRoot.innerHTML = ` <h1>Hello, Shadow DOM!</h1> `;
При този подход се създава CSSStyleSheet
обект и към него се добавят стилове с помощта на метода replaceSync()
. След това свойството adoptedStyleSheets
на Shadow Root се използва за прилагане на листа със стилове към Shadow DOM. Стиловете, дефинирани в листа със стилове, ще бъдат приложени към елементите в рамките на Shadow DOM.
От споменатите по-горе стратегии намерих използването на обекта CSSStylesSheet за ефективно и лесно за използване.
Заключение
В заключение, Shadow DOM може да се използва за капсулиране на стиловете и маркирането на компонентите, като се гарантира, че те остават незасегнати от останалата част от страницата. Това насърчава повторното използване на кода и поддръжката чрез създаване на самостоятелни елементи. Достъпността и видимостта на капсулираното съдържание могат да се контролират с помощта на отворен, затворен или режим на сянка. Освен това Shadow DOM подобрява производителността чрез минимизиране на глобалните пребоядисвания и преформатиране, като същевременно позволява прецизен обхват на стила. Като цяло предлага ефективно решение за управление на стила на компонентите, подобряване на организацията на кода и оптимизиране на производителността на уеб приложенията.