[СовеÑÑем поÑиÑаÑÑ] ÐÑÑгие 19 ÑаÑÑей Ñикла
ЧаÑÑÑ 1: ÐÐ±Ð·Ð¾Ñ Ð´Ð²Ð¸Ð¶ÐºÐ°, меÑ
анизмов вÑемени вÑполнениÑ, ÑÑека вÑзовов
ЧаÑÑÑ 2: РвнÑÑÑеннем ÑÑÑÑойÑÑве V8 и опÑимизаÑии кода
ЧаÑÑÑ 3: УпÑавление памÑÑÑÑ, ÑеÑÑÑе вида ÑÑеÑек памÑÑи и боÑÑба Ñ Ð½Ð¸Ð¼Ð¸
ЧаÑÑÑ 4: Цикл ÑобÑÑий, аÑÐ¸Ð½Ñ ÑонноÑÑÑ Ð¸ пÑÑÑ ÑпоÑобов ÑлÑÑÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð° Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ async / await
ЧаÑÑÑ 5: WebSocket и HTTP/2+SSE. ЧÑо вÑбÑаÑÑ?
ЧаÑÑÑ 6: ÐÑобенноÑÑи и ÑÑеÑа пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ WebAssembly
ЧаÑÑÑ 7: Ðеб-воÑкеÑÑ Ð¸ пÑÑÑ ÑÑенаÑиев Ð¸Ñ Ð¸ÑполÑзованиÑ
ЧаÑÑÑ 8: СеÑвиÑ-воÑкеÑÑ
ЧаÑÑÑ 9: Ðеб push-ÑведомлениÑ
ЧаÑÑÑ 10: ÐÑÑлеживание изменений в DOM Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ MutationObserver
ЧаÑÑÑ 11: Ðвижки ÑендеÑинга веб-ÑÑÑÐ°Ð½Ð¸Ñ Ð¸ ÑовеÑÑ Ð¿Ð¾ опÑимизаÑии Ð¸Ñ Ð¿ÑоизводиÑелÑноÑÑи
ЧаÑÑÑ 12: СеÑÐµÐ²Ð°Ñ Ð¿Ð¾Ð´ÑиÑÑема бÑаÑзеÑов, опÑимизаÑÐ¸Ñ ÐµÑ Ð¿ÑоизводиÑелÑноÑÑи и безопаÑноÑÑи
ЧаÑÑÑ 12: СеÑÐµÐ²Ð°Ñ Ð¿Ð¾Ð´ÑиÑÑема бÑаÑзеÑов, опÑимизаÑÐ¸Ñ ÐµÑ Ð¿ÑоизводиÑелÑноÑÑи и безопаÑноÑÑи
ЧаÑÑÑ 13: ÐнимаÑÐ¸Ñ ÑÑедÑÑвами CSS и JavaScript
ЧаÑÑÑ 14: Ðак ÑабоÑÐ°ÐµÑ JS: абÑÑÑакÑнÑе ÑинÑакÑиÑеÑкие деÑевÑÑ, паÑÑинг и его опÑимизаÑиÑ
ЧаÑÑÑ 15: Ðак ÑабоÑÐ°ÐµÑ JS: клаÑÑÑ Ð¸ наÑледование, ÑÑанÑпилÑÑÐ¸Ñ Ð² Babel и TypeScript
ЧаÑÑÑ 16: Ðак ÑабоÑÐ°ÐµÑ JS: ÑиÑÑÐµÐ¼Ñ Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
ЧаÑÑÑ 17: Ðак ÑабоÑÐ°ÐµÑ JS: ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ Shadow DOM и веб-компоненÑÑ
ЧаÑÑÑ 18: Ðак ÑабоÑÐ°ÐµÑ JS: WebRTC и Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ñ P2P-коммÑникаÑий
ЧаÑÑÑ 19: Ðак ÑабоÑÐ°ÐµÑ JS: полÑзоваÑелÑÑкие ÑлеменÑÑ
ЧаÑÑÑ 2: РвнÑÑÑеннем ÑÑÑÑойÑÑве V8 и опÑимизаÑии кода
ЧаÑÑÑ 3: УпÑавление памÑÑÑÑ, ÑеÑÑÑе вида ÑÑеÑек памÑÑи и боÑÑба Ñ Ð½Ð¸Ð¼Ð¸
ЧаÑÑÑ 4: Цикл ÑобÑÑий, аÑÐ¸Ð½Ñ ÑонноÑÑÑ Ð¸ пÑÑÑ ÑпоÑобов ÑлÑÑÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð° Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ async / await
ЧаÑÑÑ 5: WebSocket и HTTP/2+SSE. ЧÑо вÑбÑаÑÑ?
ЧаÑÑÑ 6: ÐÑобенноÑÑи и ÑÑеÑа пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ WebAssembly
ЧаÑÑÑ 7: Ðеб-воÑкеÑÑ Ð¸ пÑÑÑ ÑÑенаÑиев Ð¸Ñ Ð¸ÑполÑзованиÑ
ЧаÑÑÑ 8: СеÑвиÑ-воÑкеÑÑ
ЧаÑÑÑ 9: Ðеб push-ÑведомлениÑ
ЧаÑÑÑ 10: ÐÑÑлеживание изменений в DOM Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ MutationObserver
ЧаÑÑÑ 11: Ðвижки ÑендеÑинга веб-ÑÑÑÐ°Ð½Ð¸Ñ Ð¸ ÑовеÑÑ Ð¿Ð¾ опÑимизаÑии Ð¸Ñ Ð¿ÑоизводиÑелÑноÑÑи
ЧаÑÑÑ 12: СеÑÐµÐ²Ð°Ñ Ð¿Ð¾Ð´ÑиÑÑема бÑаÑзеÑов, опÑимизаÑÐ¸Ñ ÐµÑ Ð¿ÑоизводиÑелÑноÑÑи и безопаÑноÑÑи
ЧаÑÑÑ 12: СеÑÐµÐ²Ð°Ñ Ð¿Ð¾Ð´ÑиÑÑема бÑаÑзеÑов, опÑимизаÑÐ¸Ñ ÐµÑ Ð¿ÑоизводиÑелÑноÑÑи и безопаÑноÑÑи
ЧаÑÑÑ 13: ÐнимаÑÐ¸Ñ ÑÑедÑÑвами CSS и JavaScript
ЧаÑÑÑ 14: Ðак ÑабоÑÐ°ÐµÑ JS: абÑÑÑакÑнÑе ÑинÑакÑиÑеÑкие деÑевÑÑ, паÑÑинг и его опÑимизаÑиÑ
ЧаÑÑÑ 15: Ðак ÑабоÑÐ°ÐµÑ JS: клаÑÑÑ Ð¸ наÑледование, ÑÑанÑпилÑÑÐ¸Ñ Ð² Babel и TypeScript
ЧаÑÑÑ 16: Ðак ÑабоÑÐ°ÐµÑ JS: ÑиÑÑÐµÐ¼Ñ Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
ЧаÑÑÑ 17: Ðак ÑабоÑÐ°ÐµÑ JS: ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ Shadow DOM и веб-компоненÑÑ
ЧаÑÑÑ 18: Ðак ÑабоÑÐ°ÐµÑ JS: WebRTC и Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ñ P2P-коммÑникаÑий
ЧаÑÑÑ 19: Ðак ÑабоÑÐ°ÐµÑ JS: полÑзоваÑелÑÑкие ÑлеменÑÑ
СегоднÑ, в пеÑеводе 17 ÑаÑÑи маÑеÑиалов, поÑвÑÑÑннÑÑ Ð¾ÑобенноÑÑÑм вÑего, ÑÑо Ñак или инаÑе ÑвÑзано Ñ JavaScript, ÑеÑÑ Ð¿Ð¾Ð¹Ð´ÑÑ Ð¾ веб-компоненÑÐ°Ñ Ð¸ о ÑазлиÑнÑÑ ÑÑандаÑÑÐ°Ñ , коÑоÑÑе напÑÐ°Ð²Ð»ÐµÐ½Ñ Ð½Ð° ÑабоÑÑ Ñ Ð½Ð¸Ð¼Ð¸. ÐÑобое внимание здеÑÑ Ð±ÑÐ´ÐµÑ Ñделено ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ð¸ Shadow DOM.
ÐбзоÑ
Ðеб-компоненÑÑ â ÑÑо ÑемейÑÑво API, пÑедназнаÑеннÑÑ Ð´Ð»Ñ Ð¾Ð¿Ð¸ÑÐ°Ð½Ð¸Ñ Ð½Ð¾Ð²ÑÑ ÑлеменÑов DOM, Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑÐ¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð²ÑоÑного иÑполÑзованиÑ. ФÑнкÑионал ÑÐ°ÐºÐ¸Ñ ÑлеменÑов оÑделÑн Ð¾Ñ Ð¾ÑÑалÑного кода, Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ пÑименÑÑÑ Ð² веб-пÑиложениÑÑ ÑобÑÑвенной ÑазÑабоÑки.
СÑÑеÑÑвÑÐµÑ ÑеÑÑÑе ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ð¸, оÑноÑÑÑиеÑÑ Ðº веб-компоненÑам:
- Shadow DOM (Ñеневой DOM)
- HTML Templates (HTML-ÑаблонÑ)
- Custom Elements (полÑзоваÑелÑÑкие ÑлеменÑÑ)
- HTML Imports (HTML-импоÑÑ)
Ð ÑÑом маÑеÑиале Ð¼Ñ Ð¿Ð¾Ð³Ð¾Ð²Ð¾Ñим о ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ð¸ Shadow DOM, коÑоÑÐ°Ñ ÑазÑабоÑана Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñиложений, оÑнованнÑÑ Ð½Ð° компоненÑÐ°Ñ . Ðна пÑÐµÐ´Ð»Ð°Ð³Ð°ÐµÑ ÑпоÑÐ¾Ð±Ñ ÑеÑÐµÐ½Ð¸Ñ ÑаÑпÑоÑÑÑанÑннÑÑ Ð¿Ñоблем веб-ÑазÑабоÑки, Ñ ÐºÐ¾ÑоÑÑми вÑ, возможно, Ñже ÑÑалкивалиÑÑ:
- ÐзолÑÑÐ¸Ñ DOM: ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð¾Ð±Ð»Ð°Ð´Ð°ÐµÑ Ð¸Ð·Ð¾Ð»Ð¸ÑованнÑм деÑевом DOM (ÑÑо ознаÑаеÑ, ÑÑо команда
document.querySelector()
не Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ Ð¾Ð±ÑаÑиÑÑÑÑ Ðº ÑÐ·Ð»Ñ Ð² Ñеневом DOM компоненÑа). ÐÑоме Ñого, ÑÑо ÑпÑоÑÐ°ÐµÑ ÑиÑÑÐµÐ¼Ñ CSS-ÑелекÑоÑов в веб-пÑиложениÑÑ , Ñак как компоненÑÑ DOM изолиÑованÑ, ÑÑо даÑÑ ÑазÑабоÑÑÐ¸ÐºÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¸ÑполÑзоваÑÑ Ð¾Ð´Ð½Ð¸ и Ñе же ÑнивеÑÑалÑнÑе иденÑиÑикаÑоÑÑ Ð¸ имена клаÑÑов в ÑазлиÑнÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½ÑÐ°Ñ , не беÑпокоÑÑÑ Ð¾ возможнÑÑ ÐºÐ¾Ð½ÑликÑÐ°Ñ Ð¸Ð¼Ñн. - ÐзолÑÑÐ¸Ñ CSS: CSS-пÑавила, опиÑаннÑе внÑÑÑи Ñеневого DOM, огÑаниÑÐµÐ½Ñ Ð¸Ð¼. ÐÑи ÑÑили не покидаÑÑ Ð¿Ñеделов ÑлеменÑа, они не ÑмеÑиваÑÑÑÑ Ñ Ð´ÑÑгими ÑÑилÑми ÑÑÑаниÑÑ.
- ÐомпозиÑиÑ: ÑазÑабоÑка деклаÑаÑивного API Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñов, оÑнованного на ÑазмеÑке.
Ð¢ÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ Shadow DOM
ТÑÑ Ð¿ÑедполагаеÑÑÑ, ÑÑо Ð²Ñ Ñже Ð·Ð½Ð°ÐºÐ¾Ð¼Ñ Ñ ÐºÐ¾Ð½ÑепÑией DOM и Ñ ÑооÑвеÑÑÑвÑÑÑими API. ÐÑли ÑÑо не Ñак â можеÑе поÑиÑаÑÑ ÑÑÐ¾Ñ Ð¼Ð°ÑеÑиал.
Shadow DOM â ÑÑо, в Ñелом, Ñо же Ñамое, ÑÑо и обÑÑнÑй DOM, но Ñ Ð´Ð²ÑÐ¼Ñ Ð¾ÑлиÑиÑми:
- ÐеÑвое заклÑÑаеÑÑÑ Ð² Ñом, как Shadow DOM ÑоздаÑÑ Ð¸ иÑполÑзÑÑÑ, в ÑаÑÑноÑÑи, ÑеÑÑ Ð¸Ð´ÑÑ Ð¾Ð± оÑноÑении Shadow DOM к оÑÑалÑнÑм ÑаÑÑÑм ÑÑÑаниÑÑ.
- ÐÑоÑое заклÑÑаеÑÑÑ Ð² поведении Shadow DOM по оÑноÑÐµÐ½Ð¸Ñ Ðº ÑÑÑаниÑе.
ÐÑи ÑабоÑе Ñ DOM ÑоздаÑÑÑÑ ÑÐ·Ð»Ñ DOM, коÑоÑÑе пÑиÑоединÑÑÑÑÑ, в каÑеÑÑве доÑеÑÐ½Ð¸Ñ ÑлеменÑов, к дÑÑгим ÑлеменÑам ÑÑÑаниÑÑ. Ð ÑлÑÑае Ñ ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸ÐµÐ¹ Shadow DOM ÑоздаÑÑ Ð¸Ð·Ð¾Ð»Ð¸Ñованное деÑево DOM, коÑоÑое пÑиÑоединÑеÑÑÑ Ðº ÑлеменÑÑ, но оно оÑделено Ð¾Ñ ÐµÐ³Ð¾ обÑÑнÑÑ Ð´Ð¾ÑеÑÐ½Ð¸Ñ ÑлеменÑов.
ÐÑо изолиÑованное поддеÑево назÑваÑÑ shadow tree (Ñеневое деÑево). ÐлеменÑ, к коÑоÑÐ¾Ð¼Ñ Ð¿ÑиÑоединено Ñакое деÑево, назÑваеÑÑÑ shadow host (Ñеневой Ñ Ð¾ÑÑ-ÑлеменÑ). ÐÑÑ, ÑÑо добавлÑеÑÑÑ Ð² Ñеневое поддеÑево DOM, оказÑваеÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑм Ð´Ð»Ñ ÑлеменÑа, к коÑоÑÐ¾Ð¼Ñ Ð¾Ð½Ð¾ пÑиÑоединено, в Ñом ÑиÑле â ÑÑили, опиÑÑваемÑе Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ñегов
<style>
. Ðменно Ñак в ÑамкаÑ
ÑеÑ
нологии Shadow DOM обеÑпеÑиваеÑÑÑ Ð¸Ð·Ð¾Ð»ÑÑÐ¸Ñ CSS.Создание Shadow DOM
Shadow root (Ñеневой коÑневой ÑлеменÑ) â ÑÑо ÑÑÐ°Ð³Ð¼ÐµÐ½Ñ Ð´Ð¾ÐºÑменÑа, коÑоÑÑй пÑиÑоединÑеÑÑÑ Ðº Ñ Ð¾ÑÑ-ÑлеменÑÑ. ÐÐ»ÐµÐ¼ÐµÐ½Ñ Ð¾Ð±Ð·Ð°Ð²Ð¾Ð´Ð¸ÑÑÑ ÑеневÑм DOM Ñогда, когда к Ð½ÐµÐ¼Ñ Ð¿ÑиÑоединÑÑÑ Ñеневой коÑневой ÑлеменÑ. ÐÐ»Ñ Ñого, ÑÑÐ¾Ð±Ñ ÑоздаÑÑ Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÐµÐ³Ð¾ ÑлеменÑа Ñеневой DOM, нÑжно воÑполÑзоваÑÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ вида
element.attachShadow()
:var header = document.createElement('header');
var shadowRoot = header.attachShadow({mode: 'open'});
shadowRoot.appendChild(document.createElement('<p> Shadow DOM </p>');
Ðадо оÑмеÑиÑÑ, ÑÑо в ÑпеÑиÑикаÑии Shadow DOM имееÑÑÑ ÑпиÑок ÑлеменÑов, к коÑоÑÑм нелÑÐ·Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑаÑÑ ÑеневÑе поддеÑевÑÑ DOM.
ÐомпозиÑÐ¸Ñ Ð² Shadow DOM
ÐомпозиÑÐ¸Ñ â ÑÑо одна из важнейÑÐ¸Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑей Shadow DOM, ÑÑо ÑпоÑоб ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð²ÐµÐ±-пÑиложений, коÑоÑÑй пÑименÑеÑÑÑ Ð² пÑоÑеÑÑе напиÑÐ°Ð½Ð¸Ñ HTML-кода. Ð Ñ Ð¾Ð´Ðµ ÑÑого пÑоÑеÑÑа пÑогÑаммиÑÑ ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸ÑÑÐµÑ ÑазлиÑнÑе ÑÑÑоиÑелÑнÑе блоки (ÑлеменÑÑ), из коÑоÑÑÑ ÑоÑÑÐ¾Ð¸Ñ ÑÑÑаниÑа, вкладÑÐ²Ð°Ñ Ð¸Ñ , пÑи Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи, дÑÑг в дÑÑга. ÐапÑимеÑ, ÑÑо Ñакие ÑлеменÑÑ, как
<div>
, <header>
, <form>
, и дÑÑгие, иÑполÑзÑемÑе Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸Ð½ÑеÑÑейÑов веб-пÑиложений, в Ñом ÑиÑле, вÑÑÑÑпаÑÑие в Ñоли конÑейнеÑов Ð´Ð»Ñ Ð´ÑÑгиÑ
ÑлеменÑов.ÐомпозиÑÐ¸Ñ Ð¾Ð¿ÑеделÑÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи ÑлеменÑов, ÑÐ°ÐºÐ¸Ñ , как
<select>
, <form>
, <video>
, по вклÑÑÐµÐ½Ð¸Ñ Ð² иÑ
ÑоÑÑав дÑÑгиÑ
HTML-ÑлеменÑов в каÑеÑÑве доÑеÑниÑ
, и возможноÑÑи оÑганизаÑии оÑобого Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ ÑакиÑ
конÑÑÑÑкÑий, ÑоÑÑоÑÑиÑ
из ÑазнÑÑ
ÑлеменÑов.ÐапÑимеÑ, ÑлеменÑ
<select>
Ð¸Ð¼ÐµÐµÑ ÑÑедÑÑва Ð´Ð»Ñ ÑендеÑинга ÑлеменÑов <option>
в виде вÑпадаÑÑего ÑпиÑка Ñ Ð·Ð°Ñанее заданнÑм ÑодеÑжимÑм ÑлеменÑов Ñакого ÑпиÑка.РаÑÑмоÑÑим некоÑоÑÑе возможноÑÑи Shadow DOM пÑименÑемÑе пÑи композиÑии ÑлеменÑов.
Light DOM
Light DOM â ÑÑо ÑазмеÑка, ÑÐ¾Ð·Ð´Ð°Ð²Ð°ÐµÐ¼Ð°Ñ Ð¿Ð¾Ð»ÑзоваÑелем ваÑего компоненÑа. ÐÑÐ¾Ñ DOM Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð·Ð° пÑеделами Ñеневого DOM компоненÑа и пÑедÑÑавлÑÐµÑ Ñобой доÑеÑний ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа. ÐÑедÑÑавÑÑе Ñебе, ÑÑо Ð²Ñ Ñоздали полÑзоваÑелÑÑкий компоненÑ, назÑваемÑй
<better-button>
, коÑоÑÑй ÑаÑÑиÑÑÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи ÑÑандаÑÑного HTML-ÑлеменÑа <button>
, и полÑзоваÑÐµÐ»Ñ Ð½Ñжно добавиÑÑ Ð² ÑÑÐ¾Ñ Ð½Ð¾Ð²Ñй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¸Ð·Ð¾Ð±Ñажение и какой-Ñо ÑекÑÑ. ÐÐ¾Ñ ÐºÐ°Ðº ÑÑо вÑглÑдиÑ:<extended-button>
 <!-- Ñеги img и span - ÑÑо Light DOM ÑлеменÑа extended-button -->
 <img align="center" src="boot.png" slot="image">
 <span>Launch</span>
</extended-button>
ÐлеменÑ
<extended-button>
â ÑÑо полÑзоваÑелÑÑкий компоненÑ, опиÑаннÑй пÑогÑаммиÑÑом ÑамоÑÑоÑÑелÑно, а HTML-код внÑÑÑи ÑÑого компоненÑа â ÑÑо его Light DOM â Ñо, ÑÑо добавил в него полÑзоваÑÐµÐ»Ñ ÑÑого компоненÑа.Теневой DOM в ÑÑом пÑимеÑе â ÑÑо компоненÑ
<extended-button>
. ÐÑо â локалÑÐ½Ð°Ñ Ð¾Ð±ÑекÑÐ½Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа, коÑоÑÐ°Ñ Ð¾Ð¿Ð¸ÑÑÐ²Ð°ÐµÑ ÐµÐ³Ð¾ внÑÑÑеннÑÑ ÑÑÑÑкÑÑÑÑ, изолиÑованнÑй Ð¾Ñ Ð²Ð½ÐµÑнего миÑа CSS, и инкапÑÑлиÑÑÐµÑ Ð´ÐµÑали ÑеализаÑии компоненÑа.Flattened DOM
ÐеÑево Flattened DOM пÑедÑÑавлÑÐµÑ Ñобой Ñо, как бÑаÑÐ·ÐµÑ Ð²ÑÐ²Ð¾Ð´Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ Ð½Ð° ÑкÑан, обÑединÑÑ Light DOM и Shadow DOM. Ðменно Ñакое деÑево DOM можно видеÑÑ Ð² инÑÑÑÑменÑÐ°Ñ ÑазÑабоÑÑика, и именно оно вÑводиÑÑÑ Ð½Ð° ÑÑÑаниÑÑ. ÐÑглÑдеÑÑ ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑимеÑно Ñак:
<extended-button>
 #shadow-root
 <style>â¦</style>
 <slot name="image">
   <img align="center" src="boot.png" slot="image">
 </slot>
 <span id="container">
   <slot>
     <span>Launch</span>
   </slot>
 </span>
</extended-button>
ШаблонÑ
ÐÑли вам пÑÐ¸Ñ Ð¾Ð´Ð¸ÑÑÑ Ð¿Ð¾ÑÑоÑнно пÑименÑÑÑ Ð¾Ð´Ð½Ð¸ и Ñе же ÑÑÑÑкÑÑÑÑ Ð² HTML-ÑазмеÑке веб-ÑÑÑаниÑ, полезно бÑÐ´ÐµÑ Ð²Ð¾ÑполÑзоваÑÑÑÑ Ð½ÐµÐºÐ¸Ð¼ Ñаблоном вмеÑÑо Ñого, ÑÑÐ¾Ð±Ñ Ñнова и Ñнова пиÑаÑÑ Ð¾Ð´Ð¸Ð½ и ÑÐ¾Ñ Ð¶Ðµ код. Ðодобное бÑло возможно и ÑанÑÑе, но ÑепеÑÑ Ð²ÑÑ Ð·Ð½Ð°ÑиÑелÑно ÑпÑоÑÑилоÑÑ Ð±Ð»Ð°Ð³Ð¾Ð´Ð°ÑÑ Ð¿Ð¾ÑÐ²Ð»ÐµÐ½Ð¸Ñ HTML-Ñега
<template>
, коÑоÑÑй полÑзÑеÑÑÑ Ð¾ÑлиÑной поддеÑжкой ÑовÑеменнÑÑ
бÑаÑзеÑов. ÐÑÐ¾Ñ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¸ его ÑодеÑжимое не вÑводиÑÑÑ Ð² DOM, но Ñ Ð½Ð¸Ð¼ можно ÑабоÑаÑÑ Ð¸Ð· JavaScript. РаÑÑмоÑÑим пÑоÑÑой пÑимеÑ:<template id="my-paragraph">
 <p> Paragraph content. </p>
</template>
ÐÑли вклÑÑиÑÑ ÑакÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¸Ñ Ð² ÑоÑÑав HTML-ÑазмеÑки ÑÑÑаниÑÑ, ÑодеÑжимое опиÑÑваемого ей Ñега
<p>
не поÑвиÑÑÑ Ð½Ð° ÑкÑане до ÑеÑ
поÑ, пока не бÑÐ´ÐµÑ ÑвнÑм обÑазом пÑиÑоединено к DOM докÑменÑа. ÐапÑимеÑ, ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð²ÑглÑдеÑÑ Ñак:var template = document.getElementById('my-paragraph');
var templateContent = template.content;
document.body.appendChild(templateContent);
СÑÑеÑÑвÑÑÑ Ð¸ дÑÑгие ÑÑедÑÑва, позволÑÑÑие доÑÑиÑÑ Ñого же ÑÑÑекÑа, но, как Ñже бÑло Ñказано, ÑÐ°Ð±Ð»Ð¾Ð½Ñ â оÑÐµÐ½Ñ ÑдобнÑй ÑÑандаÑÑнÑй инÑÑÑÑменÑ, полÑзÑÑÑийÑÑ Ñ Ð¾ÑоÑей поддеÑжкой бÑаÑзеÑов.
ÐоддеÑжка HTML-Ñаблонов ÑовÑеменнÑми бÑаÑзеÑами
Ð¨Ð°Ð±Ð»Ð¾Ð½Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð¸ Ñами по Ñебе, но в полной меÑе Ð¸Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи ÑаÑкÑÑваÑÑÑÑ Ð¿Ñи иÑполÑзовании Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкими ÑлеменÑами. ÐолÑзоваÑелÑÑкие ÑлеменÑÑ â ÑÑо Ñема Ð´Ð»Ñ Ð¾ÑделÑного маÑеÑиала, а ÑейÑаÑ, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð¸Ð¼Ð°Ð½Ð¸Ñ Ð¿ÑоиÑÑ Ð¾Ð´ÑÑего, доÑÑаÑоÑно ÑÑиÑÑваÑÑ Ñо, ÑÑо API бÑаÑзеÑов
customElement
позволÑÐµÑ Ð¿ÑогÑаммиÑÑÑ Ð¾Ð¿Ð¸ÑÑваÑÑ ÑобÑÑвеннÑе HTML-Ñеги и задаваÑÑ Ñо, как ÑлеменÑÑ, ÑоздаваемÑе Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑиÑ
Ñегов, бÑдÑÑ Ð²ÑглÑдеÑÑ Ð½Ð° ÑкÑане.ÐпÑеделим веб-компоненÑ, коÑоÑÑй иÑполÑзÑÐµÑ Ð½Ð°Ñ Ñаблон в каÑеÑÑве ÑодеÑжимого Ð´Ð»Ñ Ñвоего Ñеневого DOM. ÐазовÑм ÑÑÐ¾Ñ Ð½Ð¾Ð²Ñй ÑлеменÑ
<my-paragraph>
:customElements.define('my-paragraph',
class extends HTMLElement {
  constructor() {
    super();
    let template = document.getElementById('my-paragraph');
    let templateContent = template.content;
    const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(templateContent.cloneNode(true));
 }
});
Самое важное, на ÑÑо ÑÑÑ Ð½Ð°Ð´Ð¾ обÑаÑиÑÑ Ð²Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ â ÑÑо Ñо, ÑÑо Ð¼Ñ Ð¿ÑиÑоединили клон ÑодеÑжимого Ñаблона, ÑделаннÑй Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¼ÐµÑода Node.cloneNode(), к ÑÐµÐ½ÐµÐ²Ð¾Ð¼Ñ ÐºÐ¾ÑнÑ.
Так как Ð¼Ñ Ð¿ÑиÑоединÑем ÑодеÑжимое Ñаблона к ÑÐµÐ½ÐµÐ²Ð¾Ð¼Ñ DOM, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ вклÑÑиÑÑ Ð² Ñаблон некÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑÑилизаÑии, в ÑлеменÑе <style>, коÑоÑÐ°Ñ Ð·Ð°Ñем бÑÐ´ÐµÑ Ð¸Ð½ÐºÐ°Ð¿ÑÑлиÑована в полÑзоваÑелÑÑкий ÑлеменÑ. ÐÑÑ ÑÑа ÑÑ ÐµÐ¼Ð° не бÑÐ´ÐµÑ ÑабоÑаÑÑ Ñак, как ожидаеÑÑÑ, еÑли вмеÑÑо Shadow DOM ÑабоÑаÑÑ Ñ Ð¾Ð±ÑÑнÑм DOM.
ÐапÑимеÑ, Ñаблон можно доÑабоÑаÑÑ ÑледÑÑÑим обÑазом, вклÑÑив в него ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ ÑÑилÑÑ :
<template id="my-paragraph">
 <style>
   p {
     color: white;
     background-color: #666;
     padding: 5px;
   }
 </style>
 <p>Paragraph content. </p>
</template>
ТепеÑÑ Ð¾Ð¿Ð¸ÑаннÑй нами полÑзоваÑелÑÑкий ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ Ð½Ð° обÑÑнÑÑ Ð²ÐµÐ±-ÑÑÑаниÑÐ°Ñ ÑледÑÑÑим обÑазом:
<my-paragraph></my-paragraph>
СлоÑÑ
У HTML-Ñаблонов еÑÑÑ Ð½ÐµÑколÑко недоÑÑаÑков, главнÑй из Ð½Ð¸Ñ Ð·Ð°ÐºÐ»ÑÑаеÑÑÑ Ð² Ñом, ÑÑо ÑÐ°Ð±Ð»Ð¾Ð½Ñ ÑодеÑÐ¶Ð°Ñ ÑÑаÑиÑеÑкÑÑ ÑазмеÑкÑ, ÑÑо не позволÑеÑ, напÑимеÑ, вÑводиÑÑ Ñ Ð¸Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑодеÑжимое Ð½ÐµÐºÐ¸Ñ Ð¿ÐµÑеменнÑÑ Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ ÑабоÑаÑÑ Ñ Ð½Ð¸Ð¼Ð¸ Ñак же, как ÑабоÑаÑÑ Ñо ÑÑандаÑÑнÑми HTML-Ñаблонами. ÐдеÑÑ Ð² дело вÑÑÑÐ¿Ð°ÐµÑ Ñег
<slot>
.СлоÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ воÑпÑинимаÑÑ ÐºÐ°Ðº меÑÑозаполниÑели, коÑоÑÑе позволÑÑÑ Ð²ÐºÐ»ÑÑаÑÑ Ð² Ñаблон ÑобÑÑвеннÑй HTML-код. ÐÑо позволÑÐµÑ ÑоздаваÑÑ ÑнивеÑÑалÑнÑе HTML-ÑаблонÑ, а заÑем делаÑÑ Ð¸Ñ Ð½Ð°ÑÑÑаиваемÑми, добавлÑÑ Ð² Ð½Ð¸Ñ ÑлоÑÑ.
ÐзглÑнем на Ñо, как бÑÐ´ÐµÑ Ð²ÑглÑдеÑÑ Ð²ÑÑеопиÑаннÑй Ñаблон Ñ Ð¸ÑполÑзованием Ñега
<slot>
:<template id="my-paragraph">
 <p>
   <slot name="my-text">Default text</slot>
 </p>
</template>
ÐÑли ÑодеÑжимое ÑлоÑа не задано когда ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð²ÐºÐ»ÑÑаеÑÑÑ Ð² ÑазмеÑкÑ, или еÑли бÑаÑÐ·ÐµÑ Ð½Ðµ поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑабоÑÑ Ñо ÑлоÑами, ÑлеменÑ
<my-paragraph>
бÑÐ´ÐµÑ Ð²ÐºÐ»ÑÑаÑÑ Ð² ÑÐµÐ±Ñ Ð»Ð¸ÑÑ ÑÑандаÑÑное ÑодеÑжимое Default text
.ÐÐ»Ñ Ñого ÑÑÐ¾Ð±Ñ Ð·Ð°Ð´Ð°ÑÑ ÑодеÑжимое ÑлоÑа, нÑжно вклÑÑиÑÑ Ð² ÑлеменÑ
<my-paragraph>
HTML-код Ñ Ð°ÑÑибÑÑом slot
, знаÑение коÑоÑого ÑквиваленÑно имени ÑлоÑа, в коÑоÑÑй нÑжно помеÑÑиÑÑ ÑÑÐ¾Ñ ÐºÐ¾Ð´.Ðак и Ñанее, ÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²ÑÑ, ÑÑо Ñгодно. ÐапÑимеÑ:
<my-paragraph>
<span slot="my-text">Let's have some different text!</span>
</my-paragraph>
ÐлеменÑÑ, коÑоÑÑе можно помеÑаÑÑ Ð² ÑлоÑÑ, назÑваÑÑÑÑ Slotable-ÑлеменÑами.
ÐбÑаÑиÑе внимание на Ñо, ÑÑо в пÑедÑдÑÑем пÑимеÑе Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð»Ð¸ в ÑÐ»Ð¾Ñ ÑлеменÑ
<span>
, он ÑвлÑеÑÑÑ Ñак назÑваемÑм slotted-ÑлеменÑом. У него еÑÑÑ Ð°ÑÑибÑÑ slot
, коÑоÑÐ¾Ð¼Ñ Ð¿ÑиÑвоено знаÑение my-text
, Ñо еÑÑÑ â Ñо же Ñамое знаÑение, коÑоÑое иÑполÑзовано в аÑÑибÑÑе name
ÑлоÑа, опиÑанного в Ñаблоне.ÐоÑле обÑабоÑки вÑÑеопиÑанной ÑазмеÑки бÑаÑзеÑом бÑÐ´ÐµÑ Ñоздано ÑледÑÑÑее деÑево Flattened DOM:
<my-paragraph>
 #shadow-root
 <p>
   <slot name="my-text">
     <span slot="my-text">Let's have some different text!</span>
   </slot>
 </p>
</my-paragraph>
ÐбÑаÑиÑе внимание на ÑлеменÑ
#shadow-root
. ÐÑо â вÑего лиÑÑ Ð¸Ð½Ð´Ð¸ÐºÐ°ÑÐ¾Ñ ÑÑÑеÑÑÐ²Ð¾Ð²Ð°Ð½Ð¸Ñ Shadow DOM.СÑилизаÑиÑ
ÐомпоненÑÑ, коÑоÑÑе иÑполÑзÑÑÑ ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ Shadow DOM, можно ÑÑилизоваÑÑ Ð½Ð° обÑÐ¸Ñ Ð¾ÑнованиÑÑ , они могÑÑ Ð¾Ð¿ÑеделÑÑÑ ÑобÑÑвеннÑе ÑÑили, или пÑедоÑÑавлÑÑÑ Ñ Ñки в ÑоÑме полÑзоваÑелÑÑÐºÐ¸Ñ ÑвойÑÑв CSS, коÑоÑÑе позволÑÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑм компоненÑов пеÑеопÑеделÑÑÑ ÑÑили, заданнÑе по ÑмолÑаниÑ.
âСÑили, опиÑÑваемÑе в компоненÑаÑ
ÐзолÑÑÐ¸Ñ CSS â ÑÑо одно из ÑамÑÑ Ð·Ð°Ð¼ÐµÑаÑелÑнÑÑ ÑвойÑÑв ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ð¸ Shadow DOM. Рименно, ÑеÑÑ Ð¸Ð´ÑÑ Ð¾ ÑледÑÑÑем:
- CSS-ÑелекÑоÑÑ ÑÑÑаниÑÑ, на коÑоÑой ÑазмеÑÑн ÑооÑвеÑÑÑвÑÑÑий компоненÑ, не влиÑÑÑ Ð½Ð° Ñо, ÑÑо имееÑÑÑ Ñ Ð½ÐµÐ³Ð¾ внÑÑÑи.
- СÑили, опиÑаннÑе внÑÑÑи компоненÑа, не оказÑваÑÑ Ð²Ð¾Ð·Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ Ð½Ð° ÑÑÑаниÑÑ. Ðни изолиÑÐ¾Ð²Ð°Ð½Ñ Ð² Ñ Ð¾ÑÑ-ÑлеменÑе.
CSS-ÑелекÑоÑÑ, иÑполÑзованнÑе внÑÑÑи Ñеневого DOM, пÑименÑÑÑÑÑ Ðº ÑодеÑÐ¶Ð¸Ð¼Ð¾Ð¼Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа локалÑно. Ðа пÑакÑике ÑÑо ознаÑÐ°ÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ÐºÑаÑного иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð´Ð½Ð¸Ñ Ð¸ ÑÐµÑ Ð¶Ðµ иденÑиÑикаÑоÑов и имÑн клаÑÑов в ÑазнÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½ÑÐ°Ñ Ð¸ оÑÑÑÑÑÑвие Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи беÑпокоиÑÑÑÑ Ð¾ конÑликÑÐ°Ñ Ð¸Ð¼Ñн. ÐÑоÑÑÑе CSS-ÑелекÑоÑÑ Ð¾Ð·Ð½Ð°ÑаÑÑ Ð¸ более вÑÑокÑÑ Ð¿ÑоизводиÑелÑноÑÑÑ ÑеÑений, в коÑоÑÑÑ Ð¾Ð½Ð¸ иÑполÑзÑÑÑÑÑ.
ÐзглÑнем на ÑлеменÑ
#shadow-root
, коÑоÑÑй опÑеделÑÐµÑ Ð½ÐµÐºÐ¾ÑоÑÑе ÑÑили:#shadow-root
<style>
 #container {
   background: white;
 }
 #container-items {
   display: inline-flex;
 }
</style>
<div id="container"></div>
<div id="container-items"></div>
ÐÑе вÑÑеопиÑаннÑе ÑÑили ÑвлÑÑÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑми длÑ
#shadow-root
.ÐÑоме Ñого, Ð´Ð»Ñ Ð²ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð²
#shadow-root
внеÑниÑ
ÑÐ°Ð±Ð»Ð¸Ñ ÑÑилей можно иÑполÑзоваÑÑ Ñег <link>
. Такие ÑÑили Ñоже бÑдÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑми.âÐÑевдоклаÑÑ :host
ÐÑевдоклаÑÑ
:host
позволÑÐµÑ Ð¾Ð±ÑаÑаÑÑÑÑ Ðº ÑлеменÑÑ, ÑодеÑжаÑÐµÐ¼Ñ Ñеневое деÑево DOM и ÑÑилизоваÑÑ ÑÑÐ¾Ñ ÑлеменÑ:<style>
 :host {
   display: block; /* по ÑмолÑÐ°Ð½Ð¸Ñ Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкиÑ
ÑлеменÑов ÑÑо display: inline */
 }
</style>
ÐолÑзÑÑÑÑ Ð¿ÑевдоклаÑÑом
:host
ÑледÑÐµÑ Ð¿Ð¾Ð¼Ð½Ð¸ÑÑ Ð¾ Ñом, ÑÑо пÑавила ÑодиÑелÑÑкой ÑÑÑаниÑÑ Ð¸Ð¼ÐµÑÑ Ð±Ð¾Ð»ÐµÐµ вÑÑокий пÑиоÑиÑеÑ, Ñем Ñе, коÑоÑÑе Ð·Ð°Ð´Ð°Ð½Ñ Ð² ÑлеменÑе Ñ Ð¸ÑполÑзованием ÑÑого пÑевдоклаÑÑа. ÐÑо позволÑÐµÑ Ð¿Ð¾Ð»ÑзоваÑелÑм пеÑеопÑеделÑÑÑ ÑÑили Ñ
оÑÑ-компоненÑа, заданнÑе в нÑм, извне. ÐÑоме Ñого, пÑевдоклаÑÑ :host
ÑабоÑÐ°ÐµÑ Ð»Ð¸ÑÑ Ð² конÑекÑÑе Ñеневого коÑневого ÑлеменÑа, за пÑеделами Ñеневого деÑева DOM полÑзоваÑÑÑÑ Ð¸Ð¼ нелÑзÑ.ФÑнкÑионалÑÐ½Ð°Ñ ÑоÑма пÑевдоклаÑÑа,
:host(<selector>)
, позволÑÐµÑ Ð¾Ð±ÑаÑаÑÑÑÑ Ðº Ñ
оÑÑ-ÑлеменÑÑ, еÑли он ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ ÑлеменÑÑ <selector>
. ÐÑо â оÑлиÑнÑй ÑпоÑоб, позволÑÑÑий компоненÑам инкапÑÑлиÑоваÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ, коÑоÑое ÑеагиÑÑÐµÑ Ð½Ð° дейÑÑÐ²Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð¸Ð»Ð¸ на изменение ÑоÑÑоÑÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа, и позволÑÐµÑ ÑÑилизоваÑÑ Ð²Ð½ÑÑÑенние ÑзлÑ, оÑновÑваÑÑÑ Ð½Ð° Ñ
оÑÑ-компоненÑе:<style>
 :host {
   opacity: 0.4;
 }
Â
 :host(:hover) {
   opacity: 1;
 }
Â
 :host([disabled]) { /* ÑÑилизаÑÐ¸Ñ Ð¿Ñи ÑÑловии налиÑÐ¸Ñ Ñ Ñ
оÑÑ-ÑлеменÑа аÑÑибÑÑа disabled. */
   background: grey;
   pointer-events: none;
   opacity: 0.4;
 }
Â
 :host(.pink) > #tabs {
   color: pink; /* задаÑÑ ÑÐ²ÐµÑ Ð²Ð½ÑÑÑеннего Ñзла #tabs еÑли Ñ Ñ
оÑÑ-ÑлеменÑа еÑÑÑ class="pink". */
 }
</style>
âÐ¢ÐµÐ¼Ñ Ð¸ ÑлеменÑÑ Ñ Ð¿ÑевдоклаÑÑом :host-context(<selector>)
ÐÑевдоклаÑÑ
:host-context(<selector>)
ÑооÑвеÑÑÑвÑÐµÑ Ñ
оÑÑ-ÑлеменÑÑ, еÑли он или лÑбÑе его пÑедки ÑооÑвеÑÑÑвÑÑÑ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ ÑлеменÑÑ <selector>
.ÐбÑÑнÑй ваÑÐ¸Ð°Ð½Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑой возможноÑÑи заклÑÑаеÑÑÑ Ð² ÑÑилизаÑии ÑлеменÑов Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ñем. ÐапÑимеÑ, ÑаÑÑо ÑÐµÐ¼Ñ Ð¿ÑименÑÑÑ, назнаÑÐ°Ñ ÑооÑвеÑÑÑвÑÑÑий клаÑÑ Ñегам
<html>
или <body>
:<body class="lightheme">
 <custom-container>
 â¦
 </custom-container>
</body>
ÐÑевдоклаÑÑ
:host-context(.lightheme)
бÑÐ´ÐµÑ Ð¿ÑименÑÑÑÑÑ Ðº <fancy-tabs>
в Ñом ÑлÑÑае, еÑли ÑÑÐ¾Ñ ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÑвлÑеÑÑÑ Ð¿Ð¾Ñомком .lightteme
::host-context(.lightheme) {
 color: black;
 background: white;
}
ÐонÑÑÑÑкÑиÑ
:host-context()
Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾Ð¹ Ð´Ð»Ñ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñем, но Ð´Ð»Ñ ÑÑой Ñели лÑÑÑе иÑполÑзоваÑÑ Ñ
Ñки Ñ Ð¿Ñименением полÑзоваÑелÑÑкиÑ
ÑвойÑÑв CSS.âСÑилизаÑÐ¸Ñ Ñ Ð¾ÑÑ-ÑлеменÑа компоненÑа извне
ХоÑÑ-ÑÐ»ÐµÐ¼ÐµÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа можно ÑÑилизоваÑÑ Ð¸Ð·Ð²Ð½Ðµ, иÑполÑзÑÑ Ð¸Ð¼Ñ ÐµÐ³Ð¾ Ñега в каÑеÑÑве ÑелекÑоÑа:
custom-container {
 color: red;
}
ÐнеÑние ÑÑили имеÑÑ Ð±Ð¾Ð»ÐµÐµ вÑÑокий пÑиоÑиÑеÑ, Ñем ÑÑили, опÑеделÑннÑе в Ñеневом DOM.
ÐÑедположим, полÑзоваÑÐµÐ»Ñ Ñоздал ÑледÑÑÑий ÑелекÑоÑ:
custom-container {
 width: 500px;
}
Ðн пеÑеопÑÐµÐ´ÐµÐ»Ð¸Ñ Ð¿Ñавило, заданное в Ñамом компоненÑе:
:host {
 width: 300px;
}
ÐÑполÑзÑÑ ÑÑÐ¾Ñ Ð¿Ð¾Ð´Ñ Ð¾Ð´ можно ÑÑилизоваÑÑ Ð»Ð¸ÑÑ Ñам компоненÑ. Ðак ÑÑилизоваÑÑ Ð²Ð½ÑÑÑенние ÑÑÑÑкÑÑÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа? ÐÐ»Ñ ÑÑой Ñели иÑполÑзÑÑÑÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑкие ÑвойÑÑва CSS.
âСоздание Ñ Ñков ÑÑилей Ñ Ð¸ÑполÑзованием полÑзоваÑелÑÑÐºÐ¸Ñ ÑвойÑÑв CSS
ÐолÑзоваÑели могÑÑ Ð½Ð°ÑÑÑаиваÑÑ ÑÑили внÑÑÑÐµÐ½Ð½Ð¸Ñ ÑÑÑÑкÑÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñов еÑли авÑÐ¾Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа пÑедоÑÑавлÑÐµÑ Ð¸Ð¼ Ñ Ñки ÑÑилей, пÑименÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑкие ÑвойÑÑва CSS.
РоÑнове ÑÑого Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð° Ð»ÐµÐ¶Ð¸Ñ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼, Ð¿Ð¾Ñ Ð¾Ð¶Ð¸Ð¹ на ÑоÑ, коÑоÑÑм полÑзÑÑÑÑÑ Ð¿Ñи ÑабоÑе Ñ Ñегами
<slot>
, но он, в данном ÑлÑÑае, пÑименÑеÑÑÑ Ðº ÑÑилÑм.РаÑÑмоÑÑим пÑимеÑ:
<!--âmain page -->
<style>
 custom-container {
   margin-bottom: 60px;
    -âcustom-container-bg: black;
 }
</style>
<custom-container background>â¦</custom-container>
ÐÐ¾Ñ ÑÑо Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð²Ð½ÑÑÑи Ñеневого деÑева DOM:
:host([background]) {
 background: var(â-âcustom-container-bg, #CECECE);
 border-radius: 10px;
 padding: 10px;
}
Рданном ÑлÑÑае компоненÑ, в каÑеÑÑве ÑвеÑа Ñона, иÑполÑзÑÐµÑ ÑÑÑнÑй, Ñак как именно его задал полÑзоваÑелÑ. РпÑоÑивном ÑлÑÑае ÑвеÑом Ñона бÑдеÑ
#CECECE
.Ð Ñоли авÑоÑа компоненÑа Ð²Ñ Ð¾ÑвеÑÑÑÐ²ÐµÐ½Ð½Ñ Ð·Ð° Ñо, ÑÑÐ¾Ð±Ñ ÑообÑиÑÑ ÐµÐ³Ð¾ полÑзоваÑелÑм о Ñом, какие именно полÑзоваÑелÑÑкие CSS-ÑвойÑÑва они могÑÑ Ð¸ÑполÑзоваÑÑ. СÑиÑайÑе ÑÑо ÑаÑÑÑÑ Ð¾ÑкÑÑÑого инÑеÑÑейÑа ваÑего компоненÑа.
API JavaScript Ð´Ð»Ñ ÑабоÑÑ Ñо ÑлоÑами
API Shadow DOM пÑедоÑÑавлÑÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи ÑабоÑÑ Ñо ÑлоÑами.
âСобÑÑие slotchange
СобÑÑие
slotchange
вÑзÑваеÑÑÑ Ð¿Ñи изменении Ñзлов, помеÑÑннÑÑ
в ÑлоÑ. ÐапÑимеÑ, еÑли полÑзоваÑÐµÐ»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÐµÑ Ð´Ð¾ÑеÑние ÑÐ·Ð»Ñ Ð² Light DOM или ÑдалÑÐµÑ Ð¸Ñ
из него:var slot = this.shadowRoot.querySelector('#some_slot');
slot.addEventListener('slotchange', function(e) {
 console.log('Light DOM change');
});
ÐÐ»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´ÑÑÐ³Ð¸Ñ Ñипов изменений в Light DOM, можно, в конÑÑÑÑкÑоÑе ÑлеменÑа, иÑполÑзоваÑÑ
MutationObserver
. ÐодÑобнее об ÑÑом ÑиÑайÑе здеÑÑ.âÐеÑод assignedNodes()
ÐеÑод
assignedNodes()
Ð¼Ð¾Ð¶ÐµÑ Ð¾ÐºÐ°Ð·Ð°ÑÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñм в Ñом ÑлÑÑае, еÑли нÑжно ÑзнаÑÑ Ð¾ Ñом, какие ÑлеменÑÑ ÑвÑÐ·Ð°Ð½Ñ Ñо ÑлоÑом. ÐÑзов меÑода slot.assignedNodes()
позволÑÐµÑ ÑзнаÑÑ Ð¾ Ñом, какие именно ÑлеменÑÑ Ð²ÑводÑÑÑÑ ÑÑедÑÑвами ÑлоÑа. ÐÑполÑзование опÑии {flatten: true}
позволÑÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÑÑандаÑÑное ÑодеÑжимое ÑлоÑа (вÑводимое в Ñом ÑлÑÑае, еÑли к Ð½ÐµÐ¼Ñ Ð½Ðµ бÑло пÑиÑоединено никакиÑ
Ñзлов).РаÑÑмоÑÑим пÑимеÑ:
<slot name=âslot1â><p>Default content</p></slot>
ÐÑедÑÑавим, ÑÑо ÑÑÐ¾Ñ ÑÐ»Ð¾Ñ ÑазмеÑÑн в компоненÑе
<my-container>
.ÐзглÑнем на ÑазлиÑнÑе ваÑианÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑого компоненÑа, и на Ñо, ÑÑо бÑÐ´ÐµÑ Ð²Ñдано пÑи вÑзове меÑода
assignedNodes()
.РпеÑвом ÑлÑÑае Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð»Ñем в ÑÐ»Ð¾Ñ ÑобÑÑвенное ÑодеÑжимое:
<my-container>
 <span slot="slot1"> container text </span>
</my-container>
Рданном ÑлÑÑае вÑзов
assignedNodes()
веÑнÑÑ [ container text ]
. ÐбÑаÑиÑе внимание на Ñо, ÑÑо ÑÑо знаÑение ÑвлÑеÑÑÑ Ð¼Ð°ÑÑивом Ñзлов.Ðо вÑоÑом ÑлÑÑае Ð¼Ñ Ð½Ðµ заполнÑем ÑÐ»Ð¾Ñ ÑобÑÑвеннÑм ÑодеÑжимÑм:
<my-container> </my-container>
ÐÑзов
assignedNodes()
веÑнÑÑ Ð¿ÑÑÑой маÑÑив â []
.ÐÑли, однако, пеÑедаÑÑ ÑÑÐ¾Ð¼Ñ Ð¼ÐµÑÐ¾Ð´Ñ Ð¿Ð°ÑамеÑÑ
{flatten: true}
, Ñо его вÑзов Ð´Ð»Ñ Ñого же Ñамого ÑлеменÑа вÑдаÑÑ ÐµÐ³Ð¾ ÑодеÑжимое, вÑводимое по ÑмолÑаниÑ: [
Default content
]
.ÐÑоме Ñого, Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð´Ð¾ÑÑÑп к ÑлеменÑÑ Ð²Ð½ÑÑÑи ÑлоÑа, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе вÑзваÑÑ
assignedNodes()
, ÑÑо позволиÑÑ ÑзнаÑÑ Ð¾ Ñом, ÐºÐ°ÐºÐ¾Ð¼Ñ Ð¸Ð· ÑлоÑов компоненÑа назнаÑен Ð²Ð°Ñ ÑлеменÑ.ÐÐ¾Ð´ÐµÐ»Ñ ÑобÑÑий
ÐоговоÑим о Ñом, ÑÑо пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¿Ñи вÑплÑÑии ÑобÑÑиÑ, возникÑего в Ñеневом деÑеве DOM. Ð¦ÐµÐ»Ñ ÑобÑÑÐ¸Ñ Ð·Ð°Ð´Ð°ÑÑÑÑ Ñ ÑÑÑÑом инкапÑÑлÑÑии, поддеÑживаемой ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸ÐµÐ¹ Shadow DOM. Ðогда ÑобÑÑие пеÑенапÑавлÑеÑÑÑ, ÑÑо вÑглÑÐ´Ð¸Ñ Ñак, как бÑдÑо оно иÑÑ Ð¾Ð´Ð¸Ñ Ð¾Ñ Ñамого компоненÑа, а не Ð¾Ñ ÐµÐ³Ð¾ внÑÑÑеннего ÑлеменÑа, коÑоÑÑй Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð² Ñеневом деÑеве DOM и ÑвлÑеÑÑÑ ÑаÑÑÑÑ ÑÑого компоненÑа.
ÐÐ¾Ñ ÑпиÑок ÑобÑÑий, коÑоÑÑе пеÑедаÑÑÑÑ Ð¸Ð· Ñеневого деÑева DOM (некоÑоÑÑм ÑобÑÑиÑм Ñакое поведение не ÑвойÑÑвенно):
- СобÑÑÐ¸Ñ ÑокÑÑа (Focus Events):
blur
,focus
,focusin
,focusout
. - СобÑÑÐ¸Ñ Ð¼ÑÑи (Mouse Event)s:
click
,dblclick
,mousedown
,mouseenter
,mousemove
и дÑÑгие. - СобÑÑÐ¸Ñ ÐºÐ¾Ð»ÐµÑа мÑÑи (Wheel Events):
wheel
. - СобÑÑÐ¸Ñ Ð²Ð²Ð¾Ð´Ð° (Input Events):
beforeinput
,input
. - СобÑÑÐ¸Ñ ÐºÐ»Ð°Ð²Ð¸Ð°ÑÑÑÑ (Keyboard Events):
keydown
,keyup
. - СобÑÑÐ¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð·Ð¸Ñии (Composition Events):
compositionstart
,compositionupdate
,compositionend
. - СобÑÑÐ¸Ñ Ð¿ÐµÑеÑаÑÐºÐ¸Ð²Ð°Ð½Ð¸Ñ (Drag Events):
dragstart
,drag
,dragend
,drop
, и Ñак далее.
ÐолÑзоваÑелÑÑкие ÑобÑÑиÑ
ÐолÑзоваÑелÑÑкие ÑобÑÑÐ¸Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð½Ðµ покидаÑÑ Ð¿Ñеделов Ñеневого деÑева DOM. ÐÑли Ð²Ñ Ñ Ð¾ÑиÑе вÑзваÑÑ ÑобÑÑие, и ÑÑебÑеÑÑÑ, ÑÑÐ¾Ð±Ñ Ð¾Ð½Ð¾ покинÑло пÑÐµÐ´ÐµÐ»Ñ Shadow DOM, нÑжно ÑнабдиÑÑ ÐµÐ³Ð¾ паÑамеÑÑами
bubbles: true
и composed: true
. ÐÐ¾Ñ ÐºÐ°Ðº вÑглÑÐ´Ð¸Ñ Ð²Ñзов подобного ÑобÑÑиÑ:var container = this.shadowRoot.querySelector('#container');
container.dispatchEvent(new Event('containerchanged', {bubbles: true, composed: true}));
ÐоддеÑжка Shadow DOM бÑаÑзеÑами
ÐÐ»Ñ Ñого ÑÑÐ¾Ð±Ñ ÑзнаÑÑ, поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð»Ð¸ бÑаÑÐ·ÐµÑ ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ Shadow DOM, можно пÑовеÑиÑÑ Ð½Ð°Ð»Ð¸Ñие
attachShadow
:const supportsShadowDOMV1 = !!HTMLElement.prototype.attachShadow;
ÐÐ¾Ñ ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ поддеÑжке ÑÑой ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ð¸ ÑазлиÑнÑми бÑаÑзеÑами.
ÐоддеÑжка ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ð¸ Shadow DOM в бÑаÑзеÑаÑ
ÐÑоги
Теневое деÑево DOM ведÑÑ ÑÐµÐ±Ñ Ð½Ðµ Ñак, как обÑÑное деÑево DOM. Ð ÑаÑÑноÑÑи, по Ñловам авÑоÑа данного маÑеÑиала, в библиоÑеке SessionStack ÑÑо вÑÑажаеÑÑÑ Ð² ÑÑложнении пÑоÑедÑÑÑ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ DOM, ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ коÑоÑÑÑ Ð½ÑÐ¶Ð½Ñ Ð´Ð»Ñ Ð²Ð¾ÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñого, ÑÑо пÑоиÑÑ Ð¾Ð´Ð¸Ð»Ð¾ Ñо ÑÑÑаниÑей. Рименно, Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ иÑполÑзÑеÑÑÑ
MutationObserver
. ÐÑи ÑÑом Ñеневое деÑево DOM не вÑзÑÐ²Ð°ÐµÑ ÑобÑÑÐ¸Ñ MutationObserver
в глобалÑной облаÑÑи видимоÑÑи, ÑÑо пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ Ðº необÑ
одимоÑÑи иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾ÑобÑÑ
подÑ
одов Ð´Ð»Ñ ÑабоÑÑ Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñами, иÑполÑзÑÑÑими Shadow DOM.ÐÑакÑика показÑваеÑ, ÑÑо вÑÑ Ð±Ð¾Ð»ÑÑе ÑовÑеменнÑÑ Ð²ÐµÐ±-пÑиложений иÑполÑзÑÑÑ Shadow DOM, ÑÑо позволÑÐµÑ Ð³Ð¾Ð²Ð¾ÑиÑÑ Ð¾ Ñом, ÑÑо ÑÑÑ ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ñ, веÑоÑÑно, ждÑÑ Ð´Ð°Ð»ÑнейÑее ÑазвиÑие и ÑаÑпÑоÑÑÑанение.
УважаемÑе ÑиÑаÑели! ÐолÑзÑеÑеÑÑ Ð»Ð¸ Ð²Ñ Ð²ÐµÐ±-компоненÑами, поÑÑÑоеннÑми на оÑнове ÑÐµÑ Ð½Ð¾Ð»Ð¾Ð³Ð¸Ð¸ Shadow DOM?