Автор оригинала: FreeCodeCamp Community Member.
Представьте, что вы строите сайт для клиента, небольшого магазина Mom-And-Pop, который имеет только две страницы.
Это не много. Поэтому, когда вы закончите работу на странице посадки и начните на странице контакта, вы просто создаете новый файл HTML и скопируйте все код с первой страницы.
Заголовок и нижний колонтитул уже хорошо выглядят хорошо, и все, что вам нужно сделать, это изменить остальную часть контента.
Но что, если ваш клиент хочет 10 страниц? Или 20? И они просят незначительные изменения в заголовке и нижнем колонтитуле на протяжении всего развития.
Внезапно любые изменения, независимо от того, насколько малым необходимо повторить все эти файлы.
Это одна из основных проблем, таких как React или Handlebars.js решают: любой код, особенно структурные вещи, такие как заголовок или нижний колонтитул, могут быть написаны один раз и легко повторно использовать по всему проекту.
До недавнего времени не удалось использовать компоненты в Vanilla HTML и JavaScript. Но с введением веб-компонентов можно создавать многоразовые компоненты без использования таких вещей.
Что такое веб-компоненты?
Веб-компоненты на самом деле являются коллекцией нескольких различных технологий, которые позволяют создавать пользовательские элементы HTML.
Эти технологии:
- HTML шаблоны : Фрагменты HTML Markup с использованием
<Шаблон>
Элементы, которые не будут отображаться, пока они не добавляются к странице с JavaScript. - Пользовательские элементы : Широко поддерживается API на JavaScript, которые позволяют создавать новые элементы DOM. Как только вы создадите и зарегистрируем пользовательский элемент, используя эти API, вы можете использовать его аналогично компоненту реагирования.
- Тень Дом : Меньший, инкапсулированный DOM, который выделяется от основного дома и отображается отдельно. Любые стили и сценарии, которые вы создаете для своих пользовательских компонентов в Shadow DOM, не повлияют на другие элементы в главном доме.
Мы погрузимся в каждый из них немного больше на протяжении всего учебника.
Как использовать HTML-шаблоны
Первый кусок головоломки изучает, как использовать HTML-шаблоны для создания многоразового значения HTML.
Давайте посмотрим на простое пример приветствия:
Hello, World!
And all who inhabit it
Если вы посмотрите на страницу, ни или
Элементы отображаются. Но если вы откроете консоль Dev, вы увидите оба элемента, были проанализированы:
На самом деле сделать приветственное сообщение, вам нужно будет использовать немного JavaScript:
const template = document.getElementById('welcome-msg'); document.body.appendChild(template.content);
Несмотря на то, что это довольно простой пример, вы уже можете увидеть, как использование шаблонов позволяет легко повторно использовать код по всей странице.
Основная проблема заключается в том, что, по крайней мере, с текущим примером, код приветственного сообщений смешивается с остальной частью содержимого страницы. Если вы хотите изменить приветственное сообщение позже, вам нужно изменить код в нескольких файлах.
Вместо этого вы можете вытащить шаблон HTML в файл JavaScript, поэтому любая страница JavaScript включен, будет представлять собой приветственное сообщение:
const template = document.createElement('template'); template.innerHTML = `Hello, World!
And all who inhabit it
` document.body.appendChild(template.content);
Теперь, когда все в файле JavaScript вам не нужно создавать <Шаблон>
Элемент – вы можете просто создать или
Отказ
Тем не менее, <Шаблон>
Элементы могут быть сочетаны с <Слот>
Элемент, который позволяет делать такие вещи, как изменение текста для элементов в <Шаблон>
Отказ Это немного за пределами объема этого учебника, чтобы вы могли прочитать больше о <Слот>
Элементы на MDN Отказ
Как создавать пользовательские элементы
Одна вещь, которую вы могли бы заметить с шаблонами HTML, состоит в том, что его можно сложно вставить свой код в нужном месте. Предыдущий пример приветственного сообщений был только добавлен на страницу.
Если было уже на странице, скажем, изображение баннера, приветственное сообщение появится ниже него.
Как пользовательский элемент, ваше приветственное сообщение может выглядеть так:
И вы можете поставить его везде, где вы хотите на странице.
Имея в виду, давайте посмотрим на пользовательские элементы и создайте наш собственный реагистрационный заголовок и нижний колонтитул элементы.
Настраивать
Для сайта портфолио у вас может быть какой-то код котельной, который выглядит так:
* { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; } body { color: #333; font-family: sans-serif; display: flex; flex-direction: column; } main { flex: 1 0 auto; }
Каждая страница будет иметь один и тот же заголовок и нижний колонтитул, поэтому имеет смысл создать пользовательский элемент для каждого из них.
Давайте начнем с заголовка.
Определите пользовательский элемент
Во-первых, создайте каталог под названием Компоненты
И внутри этого каталога создайте новый файл под названием header.js
со следующим кодом:
class Header extends HTMLElement { constructor() { super(); } }
Это просто простой ES5 Класс
Объявляя свой пользовательский Заголовок
Компонент, с Конструктор
Метод и специальный супер
ключевое слово. Вы можете прочитать больше о тех на MDN Отказ
Расширяя общий Htmlelement Класс, вы можете создать любой тип элемента, который вы хотите. Также возможно расширить конкретные элементы, такие как Htmlparhagelement Отказ
Зарегистрируйте свой пользовательский элемент
Прежде чем начать использовать свой пользовательский элемент, вам нужно будет зарегистрировать его с customelents.define ()
Метод:
class Header extends HTMLElement { constructor() { super(); } } customElements.define('header-component', Header);
Этот метод принимает как минимум два аргумента.
Первый – это Домстронг
Вы будете использовать при добавлении компонента на страницу в этом случае <заголовочный компонент>
Отказ
Далее – класс компонента, который вы создали ранее, здесь Заголовок
класс.
Дополнительный третий аргумент описывает, какой существующий HTML-элемент ваш пользовательский элемент наследует свойства, например, {расширяется: 'p'}
Отказ Но мы не будем использовать эту функцию в этом руководстве.
Используйте обратные вызовы жизненного цикла, чтобы добавить заголовок на страницу
Существует четыре специальных обратных вызова в жизненным цитам для пользовательских элементов, которые мы можем использовать для добавления заголовка на разметку на страницу: ConnectedCallback
, AttributeChangeCallback
, Отключенcallback
и УсыновлениеCallback
Отказ
Из этих обратных вызовов ConnectedCallback
один из наиболее часто используемых. ConnectedCallback
Запускается каждый раз, когда ваш пользовательский элемент вставлен в DOM.
Вы можете узнать больше о других обратных вызовах здесь Отказ
Для нашего простого примера ConnectedCallback
Достаточно, чтобы добавить заголовок на страницу:
class Header extends HTMLElement { constructor() { super(); } connectedCallback() { this.innerHTML = ``; } } customElements.define('header-component', Header);
Тогда в index.html
Добавьте Компоненты/header.js
Сценарий и <заголовочный компонент>
чуть выше <Главная>
элемент:
И ваш многоразовый заголовок компонента должен быть представлен на странице:
Теперь добавление заголовка на страницу так же просто, как добавление Тег указывает на
Компоненты/header.js
и добавляя <заголовочный компонент> заголовок-компонент>
где угодно.
Обратите внимание, что, поскольку заголовок и его укладка вставляются в главный дом напрямую, можно стилить его в styles.csss
файл.
Но если вы посмотрите на стили заголовка, включены в ConnectedCallback
Они довольно общие, и могут повлиять на другой стиль на странице.
Например, если мы добавим следующую компонент нижнего колонтитула:
class Footer extends HTMLElement { constructor() { super(); } connectedCallback() { this.innerHTML = ` `; } } customElements.define('footer-component', Footer);Вот что будет выглядеть страница:
Стайлинг из компонента нижнего колонтитула переопределяет стиль для заголовка, меняя цвет ссылок. Это ожидаемое поведение для CSS, но было бы неплохо, если бы укладка каждого компонента был нанесен на этот компонент, и не повлиял бы на другие вещи на странице.
Ну, именно там, где сияет тень Дом. Или оттенки? Во всяком случае, тень DOM может это сделать.
Как использовать Shadow DOM с пользовательскими элементами
Shadow DOM действует как отдельный, меньший экземпляр главного дома. Вместо того, чтобы действовать в качестве копии главного дома, Shadow DOM больше похоже на поддерево для вашего пользовательского элемента. Что-нибудь добавляемое в тень DOM, особенно стили, считают этот особый пользовательский элемент.
В некотором смысле, это как использовать
Const
иПусть
а неvar
ОтказНачнем с рефакторинга компонента заголовка:
const headerTemplate = document.createElement('template'); headerTemplate.innerHTML = ``; class Header extends HTMLElement { constructor() { super(); } connectedCallback() { } } customElements.define('header-component', Header); Первое, что вам нужно сделать, это использовать
.attachshadow ()
Метод для прикрепления корня тени к вашим элементе компонента пользовательского заголовка. ВConnectedCallback
Добавьте следующий код:... class Header extends HTMLElement { constructor() { super(); } connectedCallback() { const shadowRoot = this.attachShadow({ mode: 'closed' }); } } customElements.define('header-component', Header);Обратите внимание, что мы передаем объект на
.attachshadow ()
С опциейРежим: «Закрыто»
Отказ Это просто означает, что тень компонента заголовка недоступна от внешнего JavaScript.Если вы хотите манипулировать тенью компонента заголовка позже с JavaScript за пределами
Компоненты/header.js
Файл, просто измените опцию вРежим: «Открыть»
ОтказНаконец, добавьте
ShadowRoot
на страницу с.appendChild ()
Метод:... class Header extends HTMLElement { constructor() { super(); } connectedCallback() { const shadowRoot = this.attachShadow({ mode: 'closed' }); shadowRoot.appendChild(headerTemplate.content); } } customElements.define('header-component', Header);И теперь, поскольку стили компонента заголовка инкапсулированы в своей теневой доме, страница должна выглядеть так:
Вот что окончательный код выглядит по всем файлам после рефакторирования компонента нижнего колонтитула:
* { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; } body { color: #333; font-family: sans-serif; display: flex; flex-direction: column; } main { flex: 1 0 auto; }const headerTemplate = document.createElement('template'); headerTemplate.innerHTML = ``; class Header extends HTMLElement { constructor() { super(); } connectedCallback() { const shadowRoot = this.attachShadow({ mode: 'closed' }); shadowRoot.appendChild(headerTemplate.content); } } customElements.define('header-component', Header); const footerTemplate = document.createElement('template'); footerTemplate.innerHTML = ` `; class Footer extends HTMLElement { constructor() { super(); } connectedCallback() { const shadowRoot = this.attachShadow({ mode: 'closed' }); shadowRoot.appendChild(footerTemplate.content); } } customElements.define('footer-component', Footer);В заключение
Здесь мы здесь охватываем много, и вы, возможно, уже решили просто использовать React или Handlebars.js вместо этого.
Это оба отличные варианты!
Тем не менее, для меньшего проекта, где вам понадобится несколько многоразовых компонентов, целая библиотека или язык шаблонов могут быть излишне.
Надеюсь, теперь у вас есть уверенность, чтобы создать свои собственные многоразовые HTML-компоненты. Теперь выйдите туда и создайте что-то отличное (и многоразовую).