Веб-разработка стремительно развивается и появляются новые виды различных инструментов разработки: библиотеки и фреймворки. Их появление обусловлено необходимостью быстрой и качественной разработки веб-приложений и получения результата, которого javascript в чистом виде не всегда способен предоставить. Но и реализация новых методов, которые могут сделать разработку эффективней, продолжает происходить. Благодаря этому, хоть и не такому быстрому развитию, как хотелось бы, появились специальные веб-компоненты, которые обещают помогать делать обычными средствами javascript и браузеров то, что раньше можно было сделать только подключив определенную библиотеку или использовав фреймворк.
Web Components (Веб-компоненты) - это технология позволяющая создавать компоненты в веб-документах и веб-приложениях для многократного использования.
Веб-компоненты частично поддерживаются в браузерах Chrome, Firefox, Opera и Safari и работают напрямую без необходимости подключать какие-либо библиотеки. В остальных, где нет поддержки веб-компонентов, используется полифилы.
Полифилы - это код, реализующий функционал, которые не поддерживается по умолчанию в некоторых браузерах. Полифил является специальной библиотекой, которая подключается для поддержки стандартов HTML 5.
Веб-компоненты включают 4 технологии:
- Custom Elements — API для создания собственных HTML элементов.
- HTML Templates — тег <template> для реализации изолированные DOM-элементов
- Shadow DOM — изолирует DOM и стили в разных элементах.
- HTML Imports — импорт HTML документов.
Спецификация Web Components располагаются в GitHub репозитории webcomponents.
Спецификация веб-компонентов определяет следующие пункты:
- Новые элементы HTML: <template>
- Связанные интерфейсы API для новых элементов: HTMLTemplateElement, HTMLContentElement (удален из спецификации) и HTMLShadowElement (удален из спецификации)
- Расширения для интерфейса HTMLLinkElement и <link>
- API для регистрации встроенных элементов, Document.registerElement(), и модификации Document.createElement() и Document.createElementNS()
- Новый "жизненный цикл колбеков" может быть добавлен в прототип, на основе которого создается встроенный элемент
- Новый CSS псевдо-класс для задания стилей по умолчанию, :unresolved.
- Теневой DOM: ShadowRoot и Element.createShadowRoot(), Element.getDestinationInsertionPoints(), Element.shadowRoot
- Расширение для интерфейса Event, Event.path
- Расширение для интерфейса Document
- Для задания стилей Веб-компонент:
- Новые псевдо-классы: :host, :host(), :host-context()
- Новые псевдо-элементы: ::shadow и ::content
- Новый комбинатор, /deep/.
Custom Elements
Custom Elements (Пользовательские элементы) - эта технология позволяет создавать свои типы элементов, описывать для них свойства, методы и т.п.
Для регистрации нового элемента используется конструкция:
document.registerElement(name, { prototype: name_prototype }).
Где:
- name - имя нового элемента (тега). В названии обязательно должен быть дефис. Это сделано, чтобы предотвратить конфликт со стандартными HTML-элементами. Например, нальзя создать элемент footertop или footerTop, а название должно быть footer-top
- prototype - объект-прототип нового элемента, который должен наследовать от HTMLElement, чтобы у нового элемента были стандартные методы и свойства.
Возможно, непонятно, почему была создана новая возможность создания пользовательских элементов, поскольку уже можно создать имя тега, например, <mytag> и стилизовать его с помощью CSS, а затем использовать скрипты для прикрепления к нему поведения.
Преимущество, которое имеют Custom Elements, - это их жизненные реакции , которые позволяют привязывать поведение к различным частям «жизненного цикла» нового элемента. Например, можно установить определенное поведение, когда элемент вставлен в DOM («подключен»), и другое поведение, когда оно удаляется из DOM («отключено») или когда его атрибуты меняются.
Методы Custom Elements
Пользовательские элементы имеют следующие методы, которые определяют, как они себя ведут:
- constructor() - вызывается, когда элемент создается или обновляется
- connectedCallback() - вызывается, когда элемент вставлен в документ, в том числе в теневое дерево
- disconnectedCallback() - вызывается, когда элемент удаляется из документа
- attributeChangedCallback(attributeName, oldValue, newValue, namespace) - вызывается, когда атрибут изменяется, добавляется, удаляется или заменяется элементом.
- adoptedCallback(oldDocument, newDocument) - вызывается, когда элемент принят в новый документ
Пример Custom Elements
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product>
// Create a class for the element
class XProduct extends HTMLElement {
constructor() {
// Always call super first in constructor
super();
// Create a shadow root
var shadow = this.attachShadow({mode: 'open'});
// Create a standard img element and set its attributes.
var img = document.createElement('img');
img.alt = this.getAttribute('data-name');
img.src = this.getAttribute('data-img');
img.width = '150';
img.height = '150';
img.className = 'product-img';
// Add the image to the shadow root.
shadow.appendChild(img);
// Add an event listener to the image.
img.addEventListener('click', () => {
window.location = this.getAttribute('data-url');
});
// Create a link to the product.
var link = document.createElement('a');
link.innerText = this.getAttribute('data-name');
link.href = this.getAttribute('data-url');
link.className = 'product-name';
// Add the link to the shadow root.
shadow.appendChild(link);
}
}
// Define the new element
customElements.define('x-product', XProduct);
body {
background: #F7F7F7;
}
x-product {
display: inline-block;
float: left;
margin: 0.5em;
border-radius: 3px;
background: #FFF;
box-shadow: 0 1px 3px rgba(0,0,0,0.25);
font-family: Helvetica, arial, sans-serif;
-webkit-font-smoothing: antialiased;
}
x-product::slotted(.product-img) {
cursor: pointer;
background: #FFF;
margin: 0.5em;
}
x-product::slotted(.product-name) {
display: block;
text-align: center;
text-decoration: none;
color: #08C;
border-top: 1px solid #EEE;
font-weight: bold;
padding: 0.75em 0;
}
HTML Templates
HTML Templates - это отложенный рендер клиентского контента, который не отображается во время загрузки, но может быть инициализирован при помощи JavaScript. Парсер обрабатывает содержимое элемента <template> во время загрузки страницы, только лишь чтобы убедиться в валидности содержимого, не отображая при этом само содержимое.
У элемента <template> есть доступный только для чтения аттрибут content, предоставляющий доступ к содержимому шаблона. Проверив наличие этого атрибута помогает узнать, поддерживает ли браузет элемент <template>.
Пример HTML Templates
<table id="producttable">
<thead>
<tr>
<td>UPC_Code</td>
<td>Product_Name</td>
</tr>
</thead>
<tbody>
<!-- existing data could optionally be included here -->
</tbody>
</table>
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
// Проверяем поддерживает ли браузер тег <template>
// проверив наличие аттрибута content у элемента template
if ('content' in document.createElement('template')) {
// Instantiate the table with the existing HTML tbody and the row with the template
var t = document.querySelector('#productrow'),
td = t.content.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";
// клонируем новую строку и вставляем её в таблицу
var tb = document.getElementsByTagName("tbody");
var clone = document.importNode(t.content, true);
tb[0].appendChild(clone);
// создаём новую строку
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans";
// клонируем новую строку и вставляем её в таблицу
var clone2 = document.importNode(t.content, true);
tb[0].appendChild(clone2);
} else {
// необходимо найти другой способ добавить строку в таблицу т.к.
// тег <template> не поддерживатся браузером
}
Shadow DOM
Shadow DOM - это инкапсуляция для DOM и CSS в веб-компоненте и делает так, чтобы они оставались отдельно от DOM основного документа.
Суть инкапсуляции в том, чтобы сохранить код отдельно от остальной части страницы, когда, например, на большом сайте, не очень хорошо организован CSS и стили могут применяться в основной области содержимого, где этого делать не требуется, и наоборот.
Shadow DOM всегда должен быть привязан к существующему элементу: латеральному элементу в файле HTML, элементу созданному в DOM через js, либо пользовательским элементом.
Теневая DOM добавляется с помощью Element.attachShadow().
Пример Shadow DOM
<html>
<head></head>
<body>
<p id="hostElement"></p>
<script>
// create shadow DOM on the <p> element above
var shadow = document.querySelector('#hostElement')
.attachShadow({mode: 'open'});
</script>
</body>
</html>
shadow.innerHTML = '<span>Here is some new text</span>';
<script>
// Create shadow DOM
var shadow = document.querySelector('#hostElement')
.attachShadow({mode: 'open'});
// Add some text to shadow DOM
shadow.innerHTML = '<span>Here is some new text</span>';
// Add some CSS to make the text red
shadow.innerHTML += '<style>span { color: red; }</style>';
</script>
Shadow DOM состоит из следующих частей:
- Element.attachShadow()
- Element.getDestinationInsertionPoints()
- Element.shadowRoot
- элемент <template>
- Элемент <slot>
- Связанные интерфейсы API: ShadowRoot, HTMLTemplateElementиHTMLSlotElement
- Селекторы CSS:
- Псевдо-классы: :host, :host(),:host-context()
- Псевдо-элементы: ::slotted()
- Комбинатор: >>>*
Интерфейсы Shadow DOM
- ShadowRoot - корневой узел поддерева DOM, который отображается отдельно от основного дерева DOM документа.
- HTMLTemplateElement - включает доступ к содержимому HTML- <template>элемента.
- HTMLSlotElement - включает доступ к имени и назначенным узлам <slot>элемента HTML .
- DocumentOrShadowRoot - предоставляет API, которые совместно используются документами и теневыми корнями.
HTML Imports
HTML Imports (HTML импорт) - это механизм упаковки для веб-компонентов, но его также можно использовать сам по себе.
Импорт производится с помощью тега <link>:
<link rel="import" href="myfile.html">
Полноценные веб-компоненты будут не скоро. Кроме этого, как и все остальное в javascript, в чистом виде редко используется и применяются различные фреймворки и библиотеки, являющиеся обертками вокруг этих чистых методов для более простого использования.
Так что, можно ожидать, что веб-компоненты не заменят фреймворки и библиотеки, а войдут в их текущий функционал и будут сосуществовать наравне с ними. По крайней мере, чтобы заменить фреймворки им придется потягаться с ними. Да и, в общем-то, сами стандарты веб-компоненто, еще не до конца определены.
Как вы думаете, заменят ли Web Components фреймворки?
0 комментариев