Когда я приходил на конференции и видел презентации на тему веб-компонентов, я всегда думал, что это не только изящно, но и довольно сложно. Тысяча строк JavaScript, чтобы сохранить всего 4 строки HTML. Докладчик или неизбежно скрывал за простыми вещами огромное количество JS кода, или погружался в сложные детали, тогда мои глаза начинали закрываться от скуки, и я начинал думать о том, покрывают ли мои суточные выплаты расходы на закуски. Однако в недавнем проекте, созданном для легкого изучения HTML (Конечно, путем добавления зомби и глупых шуток), я решил, что необходимо описать каждый элемент HTML в спецификации. Не считая той конференции, я впервые начинал знакомство с <slot> и <template> элементами, и, когда я захотел написать что-то интересное о них в проекте, мне пришлось углубиться в тему.  И в процессе углубления я понял: веб-компоненты проще, чем я думал.  Либо веб-компоненты прошли долгий путь развития с тех пор, как я мечтал о закусках на конференции, либо я позволил моему изначальному страху помешать по-настоящему узнать их, а возможно и то, и другое. Я здесь, чтобы сказать вам: да, вы можете создать веб-компонент. Давайте оставим страх и даже закуски за дверью, чтобы сделать все вместе. <template> - это HTML элемент, позволяющий создать нам шаблон (HTML структуру для веб-компонентов).  Элемент <template> - очень важный, потому что позволяет держать все вместе. Это как база для вашего дома, база, с которой начинает строиться все, что мы называем готовым зданием. Давайте использовать этот небольшой фрагмент кода для нашего <apocalyptic-warning> компонента, который оповещает нас о наступлении зомби-апокалипсиса.  <slot> - это всего лишь HTML элемент, как и <template>. Но в нашем случае <slot> настраивает то, что <template> отображает на странице.  Здесь мы добавили слот со словом "Zombies" (Слово ли это?) в разметку <template>. Если мы ничего не делаем со слотом, по умолчанию он отображает контент между тегами. В нашем случае это будет "Zombies".  Использование <slot> похоже на placeholder. Мы можем использовать placeholder, тогда будет отображаться подсказка, или указать что-то другое вместоplaceholder. В веб-компонентах это достигается с помощью атрибута name. name атрибут сообщает веб-компоненту о том, какое содержание должно быть отображено в <template>. Прямо сейчас у нас есть "whats-coming" слот. Мы предполагаем, что зомби придут первыми при наступлении зомби-апокалипсиса, но <slot> дает нам гибкость, чтобы вставить что-то еще, если окажется, что первыми придут роботы или оборотни.  Технически, мы закончили писать собственный компонент и уже можем вставить в любое место, где захотим (Примечание переводчика: для полноценной работы компонента необходимо написать немного JS кода, о чем говорится далее). Видите, что мы делаем? Мы помещаем <apocalyptic-warning> компонент на страницу так же, как и любой другой HTML элемент. Однако мы добавили <span> в слот "whats-coming". <span> и его содержимое будет отображено на месте "Zombies", когда компонент отобразится.  Стоит обратить внимание, что в названиях веб-компонентов должен быть дефис, чтобы предотвратить конфликт с HTML элементами, которые могут быть добавлены браузерами позже. Это то, о чем вы должны знать, когда дело касается веб-компонентов.  Все еще со мной? Не так уж и страшно, не правда ли? Что ж, минус зомби. Нам еще надо будет немного поработать, чтобы сделать замену <slot>возможной, именно здесь мы начинаем знакомство с JavaScript.  Как я уже сказал ранее, вам нужно немного JavaScript кода, чтобы все это работало, но это не очень сложный, многострочный и глубокий код, как я всегда думал. Надеюсь, я смогу убедить вас в том, что все просто. Вам нужна функция-конструктор, которая регистрирует веб-компонент. Иначе наше компоненты будет как нежить: она есть, но не полностью живая.  Вот конструктор, который мы будем использовать.  Я оставил в коде подробные построчные комментарии, но не объяснил код на последней строке.  Мы здесь делаем много работы. Во-первых, мы берем наш веб-компонент (this) и создаем скрытого шпиона, я имею в виду Shadow DOM.{ mode: open } означает, что JavaScript может извне :root обращаться к элементам Shadow DOM и управлять ими, что-то вроде настройки доступа к компоненту через черный вход. Был создан Shadow DOM и мы добавляем к ней узел (Примечание переводчика: HTML Node). Этот узел будет полной копией шаблона, включая все элементы и текст шаблона. С шаблоном, прикрепленным к Shadow DOM из пользовательского компонента, элемент <slot> и slot атрибут берут на себя задачу сопоставления содержимого с тем, где оно должно находиться.  Проверьте это. Теперь мы можем объединить экземпляр одного и того же веб-компонента, отображая разный контент, просто изменив один элемент.  JS: HTML: Пример: Codepen Возможно, вы заметили стилизацию в нашем примере. Как и следовало ожидать, у нас есть абсолютно все возможности для стилизации наших компонентов в CSS. На самом деле, мы можем включить <style> элемент прямо в <template>. Таким образом, стили применяются только для компонента, что позволяет изолировать их благодаря теневой модели Shadow DOM.  Я предположил, что пользовательский компонент берет копию шаблона, вставляет контент, который вы добавили, и внедряет его на страницу, используя Shadow DOM. Хотя может показаться, что работа Shadow DOM похожа на обычное DOM дерево, но это не так. Контент в веб-компоненте остается на месте, а теневой DOM как бы накладывается сверху.  И с этого момента контент технически находится вне шаблона, любые селекторы и классы, используемые в шаблонном <style>, не будут действовать на контент внутри <slot>.  Это не позволяет достичь полной инкапсуляции, чего я ожидал. Но поскольку веб-компонент является элементом, мы можем использовать его как селектор элемента в любом CSS файле, включая основной файл, используемый на странице. И хотя вставленный контент технически не находится в шаблоне, он находится в веб-компоненте, где доступна стилизация через селекторы потомков CSS.  Будьте осторожны, стили в основном файле CSS не могут получить доступ к внутренним элементам <template>. Код JavaScript точно такой же, за исключением того, что сейчас мы работаем с компонентом, у которого другое имя, <zombie-profile>. Вот шаблон HTML и инкапсулированный CSS.  Вот CSS для нашего <zombie-profile> элемента и его потомков из нашего основного файла CSS. Обратите внимание, что мы используем дублирование стилей, чтобы обеспечить одинаковую стилизацию и у замененных элементов, и у элементов <template>.  А вот и результат: Пример: Codepen Несмотря на то, что есть еще пару ловушек и нюансов, я надеюсь, вы получили больше возможностей для работы с веб-компонентами, чем несколько минут назад. Возможно, будет хорошо, если вы добавите в свою работу какой-то нестандартный компонент, чтобы прочувствовать их и понять, где их использование имеет смысл. Вот и все. Чего вы сейчас боитесь больше: веб-компонентов или зомби-апокалипсиса? В недалеком прошлом я бы мог сказать, что веб-компонентов, но теперь зомби - единственное, что меня беспокоит (Ну, и покроют ли мои суточные выплаты расходы на закуски).  Software Engineer