Advertisement

Web components

Jace Lee
Front-end at Tencent
Jan. 21, 2016
Advertisement

More Related Content

Recently uploaded(20)

Advertisement

Web components

  1. Web Components wenjuli(李文举)
  2. 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>
  3. 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);
  4. 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 });
  5. 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) });
  6. 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 });
  7. Custom Elements • 与Templates and Shadow DOM结合使用 – 方便处理和复用 – template: 声明式的定义自定义元素的内容 – shadow dom: 限定内容中ID, class, style的作用域
  8. 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>
  9. 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>
  10. 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>
  11. template • 无数据绑定功能 <template bind="{{items}}"></template> <template repeat="{{item in items}}"></template> <template if="{{item.active}}"></template>
  12. shadow dom • 解决 DOM树封装问题 • 表现与内容分离 <button>Hello, world!</button> <script> var host = document.querySelector(‘button’); var root = host.createShadowRoot(); root.textContent = ‘你好,世界!’; </script>
  13. HTML Imports • 问题 – 利用custom elements, template, shadow dom创建组件,如何加载html, css, javaScript资源 – 如何删除重复依赖 • HTML Imports以一个合并的html文件加载这些资源 • 跨域导入 <link rel="import" href="component.html" >
  14. HTML Imports • 执行顺序
  15. 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 });
  16. HTML Imports • 如何在导入文档中获取其document对象? • 性能 – 重复资源只加载一次 – 利用工具合并html片断 var mainDoc = document.currentScript.ownerDocument; // mainDoc points to the document under component.html
  17. <mc-header></mc-header> <mc-aside></mc-aside> 项目文件组织应用 <link rel="import" href=”mc-frame.html">
  18. <template id="template"> <!-- <link rel="stylesheet" href="mc-header.css"> link 文件会忽略--> <style> @import url(css/mc-header.css); <!-- 路径相对于主文 件 --> </style> <div class="header"> ... </div> </template>
  19. <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>
  20. Thanks.
Advertisement