82

Олег Мохов: Веб-компоненты

  • Upload
    yandex

  • View
    2.121

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Олег Мохов: Веб-компоненты
www.princexml.com
Prince - Non-commercial License
This document was created with Prince, a great way of getting web content onto paper.
Page 2: Олег Мохов: Веб-компоненты
Page 3: Олег Мохов: Веб-компоненты

Веб-компонентыОлег Мохов

разработчик интерфейсов

26 октября 2013, ШРИ

Page 4: Олег Мохов: Веб-компоненты

GMail

Page 5: Олег Мохов: Веб-компоненты

Yandex.Mail

Page 6: Олег Мохов: Веб-компоненты
Page 7: Олег Мохов: Веб-компоненты

WebComponents● Templates

● Custom Elements

● Shadow DOM

● Imports

● Decorators

07

Page 8: Олег Мохов: Веб-компоненты

Templates

Page 9: Олег Мохов: Веб-компоненты

Templates<div id="mytemplate" hidden>

<img src="logo.png"/>

<div class="comment"></div>

</div>

01.

02.

03.

04.

09

Page 10: Олег Мохов: Веб-компоненты

Templates<script id="mytemplate" type="text/x-handlebars-template">

<img src="logo.png"/>

<div class="comment"></div>

</script>

01.

02.

03.

04.

10

Page 11: Олег Мохов: Веб-компоненты

Templates<template>

<img src="logo.png"/>

<div class="comment"></div>

</template>

01.

02.

03.

04.

11

Page 12: Олег Мохов: Веб-компоненты

Преимущества <template>1. Содержание остаётся эффективно инертным, пока оно не

активировано. По сути разметка является скрытым DOM'ом и не

рендерится.

2. Содержимое шаблона не порождает побочных эффектов: картинки не

грузятся, видео не проигрывается, скрипты не выполняются.

3. Так же внутренности шаблона не видны при выборе нод через

querySelector() или document.getElementById() .

4. Шаблоны могут находиться в любом месте, даже там, где есть строгие

ограничения на содержимое, например в <head> или <table> .

Page 13: Олег Мохов: Веб-компоненты

12

Пример <template><template>

<img src="kitten.jpg"/>

</template>

Demo

01.

02.

03.

13

Page 14: Олег Мохов: Веб-компоненты

Пример <template><template>

<img src="kitten.jpg"/>

</template>

var content = document.querySelector('template').content;

document.querySelector('#container').appendChild(

content.cloneNode(true));

01.

02.

03.

01.

02.

03.

14

Page 15: Олег Мохов: Веб-компоненты

<template> и стили1. Стили тоже не применяются, пока шаблон не активирован

2. Добавлен селектор :host(<selector>) , который позволяет

применять селекторы только на шаблон

3. НО при использовании стилей в шаблоне надо очень аккуратно

смотреть на оптимизаторы кода, которые делают структурные

изменения

15

Page 16: Олег Мохов: Веб-компоненты

Поддержка <template>: ~46%

16

Page 17: Олег Мохов: Веб-компоненты

WebComponents● Templates

● Custom Elements

● Shadow DOM

● Imports

● Decorators

17

Page 18: Олег Мохов: Веб-компоненты

CustomElements

Page 19: Олег Мохов: Веб-компоненты

Yandex.Mail

Page 20: Олег Мохов: Веб-компоненты

Yandex.Mail

Page 21: Олег Мохов: Веб-компоненты

Yandex.Mail

Page 22: Олег Мохов: Веб-компоненты

Yandex.Mail

Page 23: Олег Мохов: Веб-компоненты

Верстка почты<div class="header">...</div>

<div class="folders">...</div>

<div class="messages">...</div>

<div class="message">...</div>

01.

02.

03.

04.

23

Page 24: Олег Мохов: Веб-компоненты

Верстка почты. HTML5<header>...</header>

<div class="folders">...</div>

<div class="messages">...</div>

<div class="message">...</div>

01.

02.

03.

04.

24

Page 25: Олег Мохов: Веб-компоненты

Верстка почты. Web-Components<header>...</header>

<folders>...</folders>

<messages>...</messages>

<message>...</message>

01.

02.

03.

04.

25

Page 26: Олег Мохов: Веб-компоненты

Отзывчивость

Page 27: Олег Мохов: Веб-компоненты

Lifecycle callbackscreatedCallback

экземпляр элемента создан

enteredViewCallbackэкземпляр элемента добавлен в документ

leftViewCallbackэкземпляр элемента удалён из документа

attributeChangedCallback(attrName, oldVal, newVal)добавление/удаление/изменение аттрибута attrName

27

Page 28: Олег Мохов: Веб-компоненты

Создание кастомного элементаvar Folders = Object.create(HTMLElement.prototype);01.

28

Page 29: Олег Мохов: Веб-компоненты

Создание кастомного элементаvar Folders = Object.create(HTMLElement.prototype);

Folders.createdCallback = function() {

01.

02.

29

Page 30: Олег Мохов: Веб-компоненты

Создание кастомного элементаvar Folders = Object.create(HTMLElement.prototype);

Folders.createdCallback = function() {

this.addEventListener('click', function(e) {

alert('Thanks!');

});

};

01.

02.

03.

04.

05.

06.

30

Page 31: Олег Мохов: Веб-компоненты

Создание кастомного элементаvar Folders = Object.create(HTMLElement.prototype);

Folders.createdCallback = function() {

this.addEventListener('click', function(e) {

alert('Thanks!');

});

};

document.register('folders', {prototype: Folders});

Demo

01.

02.

03.

04.

05.

06.

07.

31

Page 32: Олег Мохов: Веб-компоненты

Lifecycle callbacksunresolved (inherits from HTMLElement)

элемент есть на странице, но не зарегистрирован через

document.register

unknown (inherits from HTMLUnknownElement)элемент браузеру не известен

Demo

32

Page 33: Олег Мохов: Веб-компоненты

Поддержка CustomElements:~45%

33

Page 34: Олег Мохов: Веб-компоненты

WebComponents● Templates

● Custom Elements

● Shadow DOM

● Imports

● Decorators

34

Page 35: Олег Мохов: Веб-компоненты
Page 36: Олег Мохов: Веб-компоненты
Page 37: Олег Мохов: Веб-компоненты
Page 38: Олег Мохов: Веб-компоненты
Page 39: Олег Мохов: Веб-компоненты

Shadow DOMShadow DOM реализует инкапсуляцию DOM-дерева. В него прячется

оформительская вёрстка, необходимая для создания визуально-

красивого контрола/виджета и т.д

http://w3c.github.io/webcomponents/spec/shadow/index.html

39

Page 40: Олег Мохов: Веб-компоненты

Shadow DOM JSvar Shadow = Object.create(HTMLElement.prototype);

Shadow.createdCallback = function() {

var shadow = this.createShadowRoot();

shadow.innerHTML = "Ололо";

};

document.register('x-browser', {prototype: Shodow});

01.

02.

03.

04.

05.

06.

40

Page 41: Олег Мохов: Веб-компоненты

Templates + Custom Elements + Shadow DOM

Page 42: Олег Мохов: Веб-компоненты

Shadow DOM JSvar Shadow = Object.create(HTMLElement.prototype);

Shadow.createdCallback = function() {

var shadow = this.createShadowRoot();

shadow.innerHTML = "Ололо";

};

document.register('x-browser', {prototype: Shodow});

01.

02.

03.

04.

05.

06.

42

Page 43: Олег Мохов: Веб-компоненты

Shadow DOM + Templatesvar Shadow = Object.create(HTMLElement.prototype);

Shadow.createdCallback = function() {

var shadow = this.createShadowRoot();

var template = document

.querySelector('template#myTemplate');

shadow.appendChild(template.content);

};

document.register('x-browser', {prototype: Shodow});

01.

02.

03.

04.

05.

06.

07.

08.

43

Page 44: Олег Мохов: Веб-компоненты

Поддержка ShadowDom: ~33%

44

Page 45: Олег Мохов: Веб-компоненты

WebComponents● Templates

● Custom Elements

● Shadow DOM

● Imports

● Decorators

45

Page 46: Олег Мохов: Веб-компоненты

Imports● <link rel="stylesheet"> для загрузки CSS

● <script src> для загрузки скриптов

● <img> для загрузки картинок

● <audio> для загрузки аудио

● <video> для загрузки видео

● ??? для загрузки HTML

46

Page 47: Олег Мохов: Веб-компоненты

Imports hacks● <iframe>

47

Page 48: Олег Мохов: Веб-компоненты

Imports hacks● <iframe> — живёт своей жизнью, т.е свой контекст относительно

текущей страницы и трудности взаимодействия JavaScript и абсолютно

невозможно стилизовать.

48

Page 49: Олег Мохов: Веб-компоненты

Imports hacks● <iframe> — живёт своей жизнью, т.е свой контекст относительно

текущей страницы и трудности взаимодействия JavaScript и абсолютно

невозможно стилизовать.

● AJAX

49

Page 50: Олег Мохов: Веб-компоненты

Imports hacks● <iframe> — живёт своей жизнью, т.е свой контекст относительно

текущей страницы и трудности взаимодействия JavaScript и абсолютно

невозможно стилизовать.

● AJAX — требует JavaScript'а :(

50

Page 51: Олег Мохов: Веб-компоненты

Imports hacks● <iframe> — живёт своей жизнью, т.е свой контекст относительно

текущей страницы и трудности взаимодействия JavaScript и абсолютно

невозможно стилизовать.

● AJAX — требует JavaScript'а :(

● хаки типа <script type="text/html">

51

Page 52: Олег Мохов: Веб-компоненты

Imports hacks● <iframe> — живёт своей жизнью, т.е свой контекст относительно

текущей страницы и трудности взаимодействия JavaScript и абсолютно

невозможно стилизовать.

● AJAX — требует JavaScript'а :(

● хаки типа <script type="text/html">

52

Page 53: Олег Мохов: Веб-компоненты

Imports<head>

<link rel="import" href="/path/to/imports/stuff.html">

</link>

01.

02.

03.

53

Page 54: Олег Мохов: Веб-компоненты

Особенности Imports● Вёрстка и CSS глобальные

● JavaScript глобальный, но поддерживает локальный скоуп через

document.currentScript.ownerDocument

● Кэширование вёрстки в браузере

● Не блокируют загрузку страницы (async)

54

Page 55: Олег Мохов: Веб-компоненты

Поддержка HTMLImports: ?

55

Page 56: Олег Мохов: Веб-компоненты

WebComponents● Templates

● Custom Elements

● Shadow DOM

● Imports

● Decorators

56

Page 57: Олег Мохов: Веб-компоненты

DecoratorsA decorator is something that enhances or overrides the presentation of

an existing element.

http://www.w3.org/TR/components-intro/#decorator-section

57

Page 58: Олег Мохов: Веб-компоненты

Decorators Example<decorator id="details-open">

<template>

<a id="summary">

&blacktriangledown;

<content select="summary"></content>

</a>

<content></content>

</template>

</decorator>

01.

02.

03.

04.

05.

06.

07.

08.

09.

Page 59: Олег Мохов: Веб-компоненты

58

Decorators Example<details open>

<summary>Timepieces</summary>

<ul>

<li>Sundial

<li>Cuckoo clock

<li>Wristwatch

</ul>

</details>

01.

02.

03.

04.

05.

06.

07.

08.

59

Page 60: Олег Мохов: Веб-компоненты

Decorators Exampledetails[open] {

decorator: url(#details-open);

}

01.

02.

03.

60

Page 61: Олег Мохов: Веб-компоненты

Decorators Example

61

Page 62: Олег Мохов: Веб-компоненты
Page 63: Олег Мохов: Веб-компоненты

BEM

Page 64: Олег Мохов: Веб-компоненты

BEM● Разделение на блоки (Imports)

● Уровни переопределения (Decorators)

● BEMJSON (Templates)

● BEMHTML (Shadow DOM)

● Блок (Custom Elements)

● Система сборки (Браузер)

64

Page 65: Олег Мохов: Веб-компоненты

<folders></folders>

{

block: 'folders'

}

01.

01.

02.

03.

65

Page 66: Олег Мохов: Веб-компоненты

BEM/BEViS ~ WebComponents

Page 67: Олег Мохов: Веб-компоненты

Будущее уже здесь!

Page 68: Олег Мохов: Веб-компоненты

i-bem.jsРеализация блока i-bem в JS. Обеспечивает хелперы для

представления блока в виде JS объекта с определёнными методами и

свойствами.

68

Page 69: Олег Мохов: Веб-компоненты

Декларативность{

block: 'folders',

js: true

}

01.

02.

03.

04.

69

Page 70: Олег Мохов: Веб-компоненты

Декларативность<div class="folders i-bem"

onclick="return {"folders":{}}">

</div>

01.

02.

03.

70

Page 71: Олег Мохов: Веб-компоненты

ДекларативностьBEM.DOM.decl('folders',

onSetMod: {

'js': function() {...}

}

});

01.

02.

03.

04.

05.

71

Page 72: Олег Мохов: Веб-компоненты

Изменение модификатораBEM.DOM.decl('folders',

onSetMod: {

'disabled': {

'yes': function() {this.setMod('aaa', 'bbb')}

}

}

});

01.

02.

03.

04.

05.

06.

07.

72

Page 73: Олег Мохов: Веб-компоненты

СобытияBEM.DOM.decl('folders',

onSetMod: {

'disabled': {

'yes': function() {this.trigger('disabled')}

}

}

});

01.

02.

03.

04.

05.

06.

07.

73

Page 74: Олег Мохов: Веб-компоненты

Событияon(e, [data], fn, [ctx])

подписка на событие e

onFirst(e, [data], fn, [ctx])подписка только на первое событие e

un([e], [fn], [ctx]) —отписка от конкретного события e или всех событий

trigger(e, [data])нотификация о событии e

74

Page 75: Олег Мохов: Веб-компоненты

Поиск элементов в терминахБЭМfindBlockInside({String})

ищет блок с заданным именем

findBlockInside({blockName: '', modName: '', modVal:''})

ищет блок с заданными именем, модификатором и значением

findBlocksInside({String|Object})ищет блоки -"-

75

Page 76: Олег Мохов: Веб-компоненты

Поиск элементов в терминахБЭМfindElem(elemName[, elemMod, elemModVal])

ищет элемент, возвращает jQuery-объект (некэширует

результат)

76

Page 77: Олег Мохов: Веб-компоненты

Поиск элементов в терминахБЭМfindElem(elemName[, elemMod, elemModVal])

ищет элемент, возвращает jQuery-объект (некэширует

результат)

elem(elemName[, elemMod, elemModVal])ищет элемент, возвращает jQuery-объект (кэширует результат)

77

Page 78: Олег Мохов: Веб-компоненты

Расширение поведенияBEM.DOM.decl({'name': 'b-link',

'modName': 'pseudo',

'modVal': 'yes'}, {

_onClick : function() {

this

.__base.apply(this, arguments)

.setMod('status', 'clicked');

}

});

01.

02.

03.

04.

05.

06.

07.

08.

09.

Page 79: Олег Мохов: Веб-компоненты

78

Итого● Веб-компоненты уже внедряются в браузеры

● Стоит следить за веб-компонентами, т.к они сильно облегчают работу

фронтендерам

● BEM == веб-компоненты. Можно использовать уже сейчас и привыкать

79

Page 80: Олег Мохов: Веб-компоненты

Ссылки● Спецификация W3C

● http://jonrimmer.github.io/are-we-componentized-yet/

● Статьи на HTML5Rocks:

– http://www.html5rocks.com/en/tutorials/webcomponents/template/

– http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/

– http://www.html5rocks.com/en/tutorials/webcomponents/customelements/

– http://www.html5rocks.com/en/tutorials/webcomponents/imports/

● Polymer Project

80

Page 81: Олег Мохов: Веб-компоненты

Домашнее задание

Page 82: Олег Мохов: Веб-компоненты

Веб-компоненты

Олег Мохов

Разработчик интерфейсов

82