SlideShare a Scribd company logo
1 of 21
Web Components
wenjuli(李文举)
Custom Elements
• How to build a custom element
• Naming rules
– 至少含有一个 ’-’
– 正确:x-component x-web-component
– 错误:web_component xelement XElement
var XComponent = document.registerElement('x-component');
<x-component></x-component>
Custom Elements
• Imperative usage
var XComponent = document.registerElement('x-component');
var dom = new XComponent();
document.body.appendChild(dom);
document.registerElement('x-component');
var dom = document.createElement('x-component');
document.body.appendChild(dom);
Custom Elements
• Adding features to a custom element
var proto = Object.create(HTMLElement.prototype);
proto.name = 'Custom Element';
proto.alert = function() {
alert('This is ' + this.name);
};
document.registerElement('x-component', {
prototype: proto
});
Custom Elements
• Type Extension Custom Element
– 自定义元素可以是从扩展原生HTML元素而来
– 定义类型扩展
• 创建基本原型对象,使用被扩展元素的原型,而不是使用HTMLElement
• 在document.registerElement()的第二个参数中添加 extends 键,值为被扩展元素的标签名
<div is="x-component"></div>
var XComponent = document.registerElement('x-component', {
extends: 'input',
prototype: Object.create(HTMLInputElement.prototype)
});
Custom Elements
• Lifecycle callbacks DEMO
– .createdCallback()
– .attachedCallback()
– .detachedCallback()
– .attributeChangedCallback()
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function() {
var div = document.createElement('div');
div.textContent = 'This is Custom Element';
this.appendChild(div);
};
var XComponent = document.registerElement('x-component', {
prototype: proto
});
Custom Elements
• 与Templates and Shadow DOM结合使用
– 方便处理和复用
– template: 声明式的定义自定义元素的内容
– shadow dom: 限定内容中ID, class, style的作用域
template
<div style="display:none;">
<div>
<h1>Web Components</h1>
<img src="http://webcomponents.org/img/logo.svg">
</div>
</div>
<script type="text/template">
<div>
<h1>Web Components</h1>
<img src="http://webcomponents.org/img/logo.svg">
</div>
</script>
template
• 惰性HTML标签
– 行内脚本不执行
– 资源(如<img>, <video>)不加载
• 定义template
<template id="template">
<style>
...
</style>
<div>
<h1>Web Components</h1>
<img src="http://webcomponents.org/img/logo.svg">
</div>
</template>
template
• 使用template内容
– http://jsbin.com/qaxiw/7/edit?html,css,output
<script>
var template = document.querySelector('#template');
var clone = document.importNode(template.content, true);
var host = document.querySelector('#host');
host.appendChild(clone);
</script>
<div id="host"></div>
template
• 无数据绑定功能
<template bind="{{items}}"></template>
<template repeat="{{item in items}}"></template>
<template if="{{item.active}}"></template>
shadow dom
• 解决 DOM树封装问题
• 表现与内容分离
<button>Hello, world!</button>
<script>
var host = document.querySelector(‘button’);
var root = host.createShadowRoot();
root.textContent = ‘你好,世界!’;
</script>
HTML Imports
• 问题
– 利用custom elements, template, shadow dom创建组件,如何加载html, css,
javaScript资源
– 如何删除重复依赖
• HTML Imports以一个合并的html文件加载这些资源
• 跨域导入
<link rel="import" href="component.html" >
HTML Imports
• 执行顺序
HTML Imports
• 导入文档中脚本在导入时会执行,但HTML标签并不会渲染,需要脚
本来处理
• 注意:导入文档中的document对象实际上指的是主文件的document对
象。
• 如何在主文档中引用导入文档中的document对象?
var link = document.querySelector('link[rel="import"]');
link.addEventListener('load', function(e) {
var importedDoc = link.import;
// importedDoc points to the document under
component.html
});
HTML Imports
• 如何在导入文档中获取其document对象?
• 性能
– 重复资源只加载一次
– 利用工具合并html片断
var mainDoc = document.currentScript.ownerDocument;
// mainDoc points to the document under component.html
<mc-header></mc-header>
<mc-aside></mc-aside>
项目文件组织应用
<link rel="import" href=”mc-frame.html">
<template id="template">
<!-- <link rel="stylesheet" href="mc-header.css"> link
文件会忽略-->
<style>
@import url(css/mc-header.css); <!-- 路径相对于主文
件 -->
</style>
<div class="header">
...
</div>
</template>
<script>
(function(doc){
var McHeader = document.registerElement('mc-header', {
prototype: Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var root = this.createShadowRoot();
var template =
doc.querySelector('#template');
var clone =
document.importNode(template.content, true);
root.appendChild(clone);
}
}
})
});
})(document.currentScript.ownerDocument);
</script>
Thanks.

More Related Content

Viewers also liked

HealthCARE Montana and EdReady June 2015
HealthCARE Montana and EdReady June 2015HealthCARE Montana and EdReady June 2015
HealthCARE Montana and EdReady June 2015Ryan Schrenk
 
Michael allen's dumbest mistakes ever
Michael allen's dumbest mistakes everMichael allen's dumbest mistakes ever
Michael allen's dumbest mistakes everMichael Allen
 
视觉隐藏内容
视觉隐藏内容视觉隐藏内容
视觉隐藏内容Jace Lee
 
Our Wedding Pictures
Our Wedding PicturesOur Wedding Pictures
Our Wedding Picturesjohn dorman
 
China Speaking Series - Talent and Accelerated Development Guangzhou March ...
China Speaking Series - Talent and Accelerated Development   Guangzhou March ...China Speaking Series - Talent and Accelerated Development   Guangzhou March ...
China Speaking Series - Talent and Accelerated Development Guangzhou March ...ksteadman
 
Motivational posters collection (c-d)
Motivational posters collection (c-d)Motivational posters collection (c-d)
Motivational posters collection (c-d)Vu The Du
 
Our interview with Mrs Reid
Our interview with Mrs ReidOur interview with Mrs Reid
Our interview with Mrs ReidLesa Lafaelle
 
1999 European Vacation
1999 European Vacation1999 European Vacation
1999 European Vacationjohn dorman
 
Tomorrow Never Knows (The Beatles)
Tomorrow Never Knows (The Beatles)Tomorrow Never Knows (The Beatles)
Tomorrow Never Knows (The Beatles)Bernard Richeux
 
What Social Media Can Learn From #MadMen
What Social Media Can Learn From #MadMen What Social Media Can Learn From #MadMen
What Social Media Can Learn From #MadMen Beyond
 
D Aily%20 Routine%20 Cards
D Aily%20 Routine%20 CardsD Aily%20 Routine%20 Cards
D Aily%20 Routine%20 Cardsguest5c25077
 
Familiespektakel Blixembosch 2016
Familiespektakel Blixembosch 2016Familiespektakel Blixembosch 2016
Familiespektakel Blixembosch 2016Twan van den Broek
 

Viewers also liked (20)

響應式網頁教學
響應式網頁教學響應式網頁教學
響應式網頁教學
 
HealthCARE Montana and EdReady June 2015
HealthCARE Montana and EdReady June 2015HealthCARE Montana and EdReady June 2015
HealthCARE Montana and EdReady June 2015
 
Pub
PubPub
Pub
 
Lonnie
LonnieLonnie
Lonnie
 
Nt3
Nt3Nt3
Nt3
 
Michael allen's dumbest mistakes ever
Michael allen's dumbest mistakes everMichael allen's dumbest mistakes ever
Michael allen's dumbest mistakes ever
 
G3a1 lo2q
G3a1 lo2qG3a1 lo2q
G3a1 lo2q
 
视觉隐藏内容
视觉隐藏内容视觉隐藏内容
视觉隐藏内容
 
Our Wedding Pictures
Our Wedding PicturesOur Wedding Pictures
Our Wedding Pictures
 
Logica Imbatranirii
Logica ImbatraniriiLogica Imbatranirii
Logica Imbatranirii
 
China Speaking Series - Talent and Accelerated Development Guangzhou March ...
China Speaking Series - Talent and Accelerated Development   Guangzhou March ...China Speaking Series - Talent and Accelerated Development   Guangzhou March ...
China Speaking Series - Talent and Accelerated Development Guangzhou March ...
 
Motivational posters collection (c-d)
Motivational posters collection (c-d)Motivational posters collection (c-d)
Motivational posters collection (c-d)
 
Thanksgiving Poem
Thanksgiving  PoemThanksgiving  Poem
Thanksgiving Poem
 
Our interview with Mrs Reid
Our interview with Mrs ReidOur interview with Mrs Reid
Our interview with Mrs Reid
 
1999 European Vacation
1999 European Vacation1999 European Vacation
1999 European Vacation
 
Tomorrow Never Knows (The Beatles)
Tomorrow Never Knows (The Beatles)Tomorrow Never Knows (The Beatles)
Tomorrow Never Knows (The Beatles)
 
What Social Media Can Learn From #MadMen
What Social Media Can Learn From #MadMen What Social Media Can Learn From #MadMen
What Social Media Can Learn From #MadMen
 
D Aily%20 Routine%20 Cards
D Aily%20 Routine%20 CardsD Aily%20 Routine%20 Cards
D Aily%20 Routine%20 Cards
 
Familiespektakel Blixembosch 2016
Familiespektakel Blixembosch 2016Familiespektakel Blixembosch 2016
Familiespektakel Blixembosch 2016
 
Weather Adaptado
Weather AdaptadoWeather Adaptado
Weather Adaptado
 

Web components

  • 2.
  • 3. Custom Elements • How to build a custom element • Naming rules – 至少含有一个 ’-’ – 正确:x-component x-web-component – 错误:web_component xelement XElement var XComponent = document.registerElement('x-component'); <x-component></x-component>
  • 4. Custom Elements • Imperative usage var XComponent = document.registerElement('x-component'); var dom = new XComponent(); document.body.appendChild(dom); document.registerElement('x-component'); var dom = document.createElement('x-component'); document.body.appendChild(dom);
  • 5. Custom Elements • Adding features to a custom element var proto = Object.create(HTMLElement.prototype); proto.name = 'Custom Element'; proto.alert = function() { alert('This is ' + this.name); }; document.registerElement('x-component', { prototype: proto });
  • 6. Custom Elements • Type Extension Custom Element – 自定义元素可以是从扩展原生HTML元素而来 – 定义类型扩展 • 创建基本原型对象,使用被扩展元素的原型,而不是使用HTMLElement • 在document.registerElement()的第二个参数中添加 extends 键,值为被扩展元素的标签名 <div is="x-component"></div> var XComponent = document.registerElement('x-component', { extends: 'input', prototype: Object.create(HTMLInputElement.prototype) });
  • 7. Custom Elements • Lifecycle callbacks DEMO – .createdCallback() – .attachedCallback() – .detachedCallback() – .attributeChangedCallback() var proto = Object.create(HTMLElement.prototype); proto.createdCallback = function() { var div = document.createElement('div'); div.textContent = 'This is Custom Element'; this.appendChild(div); }; var XComponent = document.registerElement('x-component', { prototype: proto });
  • 8. Custom Elements • 与Templates and Shadow DOM结合使用 – 方便处理和复用 – template: 声明式的定义自定义元素的内容 – shadow dom: 限定内容中ID, class, style的作用域
  • 9. template <div style="display:none;"> <div> <h1>Web Components</h1> <img src="http://webcomponents.org/img/logo.svg"> </div> </div> <script type="text/template"> <div> <h1>Web Components</h1> <img src="http://webcomponents.org/img/logo.svg"> </div> </script>
  • 10. template • 惰性HTML标签 – 行内脚本不执行 – 资源(如<img>, <video>)不加载 • 定义template <template id="template"> <style> ... </style> <div> <h1>Web Components</h1> <img src="http://webcomponents.org/img/logo.svg"> </div> </template>
  • 11. template • 使用template内容 – http://jsbin.com/qaxiw/7/edit?html,css,output <script> var template = document.querySelector('#template'); var clone = document.importNode(template.content, true); var host = document.querySelector('#host'); host.appendChild(clone); </script> <div id="host"></div>
  • 12. template • 无数据绑定功能 <template bind="{{items}}"></template> <template repeat="{{item in items}}"></template> <template if="{{item.active}}"></template>
  • 13. shadow dom • 解决 DOM树封装问题 • 表现与内容分离 <button>Hello, world!</button> <script> var host = document.querySelector(‘button’); var root = host.createShadowRoot(); root.textContent = ‘你好,世界!’; </script>
  • 14. HTML Imports • 问题 – 利用custom elements, template, shadow dom创建组件,如何加载html, css, javaScript资源 – 如何删除重复依赖 • HTML Imports以一个合并的html文件加载这些资源 • 跨域导入 <link rel="import" href="component.html" >
  • 16. HTML Imports • 导入文档中脚本在导入时会执行,但HTML标签并不会渲染,需要脚 本来处理 • 注意:导入文档中的document对象实际上指的是主文件的document对 象。 • 如何在主文档中引用导入文档中的document对象? var link = document.querySelector('link[rel="import"]'); link.addEventListener('load', function(e) { var importedDoc = link.import; // importedDoc points to the document under component.html });
  • 17. HTML Imports • 如何在导入文档中获取其document对象? • 性能 – 重复资源只加载一次 – 利用工具合并html片断 var mainDoc = document.currentScript.ownerDocument; // mainDoc points to the document under component.html
  • 19. <template id="template"> <!-- <link rel="stylesheet" href="mc-header.css"> link 文件会忽略--> <style> @import url(css/mc-header.css); <!-- 路径相对于主文 件 --> </style> <div class="header"> ... </div> </template>
  • 20. <script> (function(doc){ var McHeader = document.registerElement('mc-header', { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: function() { var root = this.createShadowRoot(); var template = doc.querySelector('#template'); var clone = document.importNode(template.content, true); root.appendChild(clone); } } }) }); })(document.currentScript.ownerDocument); </script>