Web Components 是个怎么样的事物

2016/09/04 · HTML5,
JavaScript · Web
Components

初稿出处: teabyii   

前端组件化这一个主题相关的内容早就火了很久很久,angular 刚出来时的
Directive 到 angular2 的 components,还有 React 的components
等等,无一不是前端组件化的一种完结和探寻,不过提上议程的 Web Components
标准是个如何的事物,相关的局部框架恐怕类库,如 React,Angular2,以致是
x-tag,polymer 未来实现的组件化的事物和 Web Components
规范差异在何地?小编花时间努力地把现成的 W3C Web
Components
文书档案看了下,然后坚强地写下这个记录。

首先大家必要知道,Web Components 包涵了五个部分:

  • Custom Elements
  • HTML Imports
  • HTML
    Templates
  • Shadow DOM

那四有的有机地构成在一道,才是 Web Components。

可以用自定义的竹签来引进组件是前者组件化的基础,在页面引用 HTML 文件和
HTML 模板是用来援救编写组件视图和零部件财富管理,而 Shadow DOM
则是与世隔膜组件间代码的顶牛和熏陶。

上边分别是每一片段的笔记内容。

Custom Elements

概述

Custom Elements 看名就能够猜到其意义,是提供一种方法让开垦者能够自定义 HTML
元素,包涵特定的咬合,样式和作为。帮忙 Web Components
标准的浏览器会提供一密密麻麻 API
给开采者用于创制自定义的要素,大概扩张现存成分。

这一项专门的学问的草案还处于不地西泮的事态,时有更新,API
还恐怕会全数变动,上边的笔记以 Cutsom Elements
2016.02.26
这一个本子为准,因为在风行的 chrome 浏览器已经是能够干活的了,那样能够选用demo 来做尝试,最后笔者会再轻巧写一下新型文书档案和那一个的分歧。

registerElement

先是,大家能够品尝在 chrome 调整台输入
HTMLInputElement,能够看看是有这么贰个东西的,那么些通晓为 input DOM
成分实例化时的构造函数,基础的是 HTMLElement

Web Components 标准建议提供这么贰个接口:

JavaScript

document.registerElement(‘x-foo’, { prototype:
Object.create(HTMLElement.prototype, { createdCallback: { value:
function() { … } }, … }) })

1
2
3
4
5
6
7
8
document.registerElement(‘x-foo’, {
  prototype: Object.create(HTMLElement.prototype, {
    createdCallback: {      
      value: function() { … }
    },
    …
  })
})

您可以行使 document.registerElement 来注册叁个标签,典型中为了提供
namesapce 的支撑,幸免争持,规定标签类型(也足以知道为名字)需求运用 -
连接。同期,不可能是以下那有的:

  • annotation-xml
  • color-profile
  • font-face
  • font-face-src
  • font-face-uri
  • font-face-format
  • font-face-name
  • missing-glyph

第贰个参数是标签相关的安排,首借使提供贰个 prototype,那个原型对象是以
HTMLElement 等的原型为根基创造的靶子。然后你便能够在 HTML
中去行使自定义的标签。如:

XHTML

<div> <x-foo></x-foo> </div>

1
2
3
<div>
  <x-foo></x-foo>
</div>

是否嗅到了 React 的含意?好啊,React 说它本人紧要不是做这几个事情的。

生命周期和回调

在那么些 API 的底子上,Web Components
标准提供了一多级决定自定义成分的形式。大家来千家万户看下:

叁个自定义成分会经历以下这一个生命周期:

  • 注册前创办
  • 登记自定义成分定义
  • 在注册后创制作而成分实例
  • 要素插入到 document 中
  • 元素从 document 中移除
  • 要素的品质变化时

以此是很重大的内容,开荒者可以在注册新的自定义成分时钦命相应的生命周期回调来为自定义元素加多种种自定义的行事,那么些生命周期回调包涵了:

  • createdCallback
    自定义成分注册后,在实例化之后会调用,平常多用来做成分的开头化,如插入子成分,绑定事件等。
  • attachedCallback
    要素插入到 document 时接触。
  • detachedCallback
    要素从 document 中移除时接触,大概会用来做类似 destroy 之类的职业。
  • attributeChangedCallback
    要素属性别变化化时接触,能够用于从外到内的通讯。外部通过更动成分的习性来让里面获得有关的数据同期施行相应的操作。

其一回调在不一样景况下有对应分歧的参数:

  • 安装属性时,参数列表是:属性名称,null,值,命名空间
  • 修改属性时,参数列表是:属性名称,旧值,新值,命名空间
  • 删除属性时,参数列表是:属性名称,旧值,null,命名空间

好了,就下边明白到的根底上,假如我们要创设多少个自定义的 button-hello
开关,点击时会 alert('hello world'),代码如下:

JavaScript

document.registerElement(‘button-hello’, { prototype:
Object.create(HTMLButtonElement.prototype, { createdCallback: { value:
function createdCallback() { this.innerHTML = ‘<button>hello
world</button>’ this.addEventListener(‘click’, () => {
alert(‘hello world’) }) } } }) })

1
2
3
4
5
6
7
8
9
10
11
12
document.registerElement(‘button-hello’, {
  prototype: Object.create(HTMLButtonElement.prototype, {
    createdCallback: {
      value: function createdCallback() {
        this.innerHTML = ‘<button>hello world</button>’
        this.addEventListener(‘click’, () => {
          alert(‘hello world’)
        })
      }
    }
  })
})

要注意上述代码施行之后能力利用 <button-hello></button-hello>

扩充原有成分

实在,若是大家要求一个开关,完全不需求再行自定义八个成分,Web Components
规范提供了一种扩展现存标签的方法,把上边包车型客车代码调治一下:

JavaScript

document.registerElement(‘button-hello’, { prototype:
Object.create(HTMLButtonElement.prototype, { createdCallback: { value:
function createdCallback() { this.addEventListener(‘click’, () => {
alert(‘hello world’) }) } } }), extends: ‘button’ })

1
2
3
4
5
6
7
8
9
10
11
12
document.registerElement(‘button-hello’, {
  prototype: Object.create(HTMLButtonElement.prototype, {
    createdCallback: {
      value: function createdCallback() {
        this.addEventListener(‘click’, () => {
          alert(‘hello world’)
        })
      }
    }
  }),
  extends: ‘button’
})

接下来在 HTML 中要这么使用:

XHTML

<button is=”button-hello”>hello world</button>

1
<button is="button-hello">hello world</button>

使用 is
属性来声称一个增加的体系,看起来也蛮酷的。生命周期和自定义成分标签的保持一致。

当大家须求八个标签组合成新的要素时,大家能够利用自定义的要素标签,不过借使只是亟需在原来的
HTML 标签上海展览中心开扩展的话,使用 is 的这种成分扩大的措施就好。

原有的 createElementcreateElementNS,在 Web Components
典型中也扩展成为援助成分扩大,举例要创立一个 button-hello

JavaScript

const hello = document.createElement(‘button’, ‘button-hello’)

1
const hello = document.createElement(‘button’, ‘button-hello’)

行业内部文书档案中还大概有为数非常多细节上的内容,比如接口的参数表达和要求,回调队列的兑现须求等,那几个更多是对于落实那个专门的学业的浏览器开荒者的渴求,这里不做详细描述了,内容大多,风乐趣的活动查阅:Cutsom
Elements
2016.02.26。

和流行版的界别

前方笔者关系说文书档案的立异改变相当的慢,停止至笔者写那一个稿子的时候,最新的文书档案是这一个:Custom
Elements 2016.07.21。

细节不做描述了,讲讲笔者看看的最大变化,正是向 ES6 靠拢。大约有上边三点:

  • 从原来的扩大 prototype 来定义成分调节为提出使用 class extends 的主意
  • 挂号自定义元素接口调治,越发方便使用,传入 type 和 class 就能够
  • 生命周期回调调度,createdCallback 直接用 class 的 constructor

前三个点,我们直接看下代码,原来的代码根据新的正式,应该调度为:

JavaScript

class ButtonHelloElement extends HTMLButtonElement { constructor() {
super() this.addEventListener(‘click’, () => { alert(‘hello world’)
}) } } customElements.define(‘button-hello’, ButtonHelloElement, {
extends: ‘button’ })

1
2
3
4
5
6
7
8
9
10
11
class ButtonHelloElement extends HTMLButtonElement {
  constructor() {
    super()
 
    this.addEventListener(‘click’, () => {
      alert(‘hello world’)
    })
  }
}
 
customElements.define(‘button-hello’, ButtonHelloElement, { extends: ‘button’ })

从代码上看会深感更加的OO,编写上也比原本要出示方便一些,原来的生命周期回调是调解为新的:

  • constructor in class 效用也正是原本的 createdCallback
  • connectedCallback 功用约等于 attachedCallback
  • disconnectedCallback 成效约等于 detachedCallback
  • adoptedCallback 使用 document.adoptNode(node) 时触发
  • attributeChangedCallback 和原本保持一致

connect 事件和插入成分到 document 有多少组别,首要正是插入成分到
document 时,成分状态会成为 connected,那时会触发
connectedCallback,disconnect 亦是那般。

HTML Imports

概述

HTML Imports 是一种在 HTMLs 中援引以及复用其余的 HTML 文书档案的秘技。那几个Import 很美,能够省略通晓为大家广大的模板中的include 之类的效应。

大家最广大的引入三个 css 文件的法子是:

XHTML

<link rel=”stylesheet” href=”/css/master.css”>

1
<link rel="stylesheet" href="/css/master.css">

Web Components 以往提供多了八个这一个:

XHTML

<link rel=”import” href=”/components/header.html”>

1
<link rel="import" href="/components/header.html">

HTMLLinkElement

原本的 link 标签在增加了 HTML Import 之后,多了二个只读的 import
属性,当出现上面二种情状时,那本性情为 null

  • link 不是用来 import 叁个 HTML 的。
  • link 成分不在 document 中。

再不,那本性情会回来一个象征引入的 HTML 文件的文书档案对象,类似于
document。举例说,在上边的代码基础上,能够那样做:

JavaScript

const link = document.querySelector(‘link[rel=import]’) const header =
link.import; const pulse = header.querySelector(‘div.logo’);

1
2
3
4
const link = document.querySelector(‘link[rel=import]’)
const header = link.import;
 
const pulse = header.querySelector(‘div.logo’);

阻塞式

前者组件化这些宗旨相关的剧情早就火了很久很久。咱俩要领悟的是,私下认可的 link 加载是阻塞式的,除非您给他增添二个 async
标识。

阻塞式从某种程度上讲是有不可缺少的,当您 improt
的是三个完好的自定义组件并且须求在主 HTML
中用竹签直接运用时,非阻塞的就能够并发谬误了,因为标签还尚无被登记。

document

有好几值得注意的是,在 import 的 HTML 中,大家编辑的 script 里边的
document 是指向 import 这个 HTML 的主 HTML 的 document。

固然大家要博取 import 的 HTML 的 document 的话,得如此来:

JavaScript

const d = document.currentScript.ownerDocument

1
const d = document.currentScript.ownerDocument

如此那般设计是因为 import 进来的 HTML 须求用到主 HTML 的
document。例如大家上面提到的 registerElement

在一个被 import 的 HTML 文件中动用下面七个方法会抛出多少个
InvalidStateError
异常:

  • document.open()
  • document.write()
  • document.close()

对于 HTML
Import,标准文书档案中还应该有相当大学一年级部分剧情是有关五个依赖加载的拍卖算法的,在那边就不详述了,有机会的话找时间再开篇谈,那几个内容是急需浏览器去贯彻的。

HTML Templates

概述

其一事物比非常粗大略,用过 handlebars 的人都精晓有诸如此类二个东西:

XHTML

<script id=”template” type=”text/x-handlebars-template”> …
</script>

1
2
3
<script id="template" type="text/x-handlebars-template">
  …
</script>

其余模板引擎也会有相近的事物,那么 HTML Templates
便是把那一个东西官方口径,提供了一个 template
标签来存放以往要求可是近期不渲染的 HTML 代码。

从此能够这么写了:

XHTML

<template id=”template”> … </template>

1
2
3
<template id="template">
  …
</template>

接口和采取

template 成分有叁个只读的属性 content,用于再次回到那么些 template
里边的剧情,重回的结果是三个 DocumentFragment

切实是怎么运用的,直接参考官方给出的例证:

XHTML

<!doctype html> <html lang=”en”> <head>
<title>Homework</title> <body> <template
id=”template”><p>Smile!</p></template>
<script> let num = 3; const fragment =
document.getElementById(‘template’).content.cloneNode(true); while
(num– > 1) {
fragment.firstChild.before(fragment.firstChild.cloneNode(true));
fragment.firstChild.textContent += fragment.lastChild.textContent; }
document.body.appendChild(fragment); </script> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!doctype html>
<html lang="en">
  <head>
    <title>Homework</title>
  <body>
    <template id="template"><p>Smile!</p></template>
    <script>
      let num = 3;
      const fragment = document.getElementById(‘template’).content.cloneNode(true);
      while (num– > 1) {
        fragment.firstChild.before(fragment.firstChild.cloneNode(true));
        fragment.firstChild.textContent += fragment.lastChild.textContent;
      }
      document.body.appendChild(fragment);
    </script>
</html>

使用 DocumentFragment 的 clone 方法以 template
里的代码为根基创立三个因早秋点,然后您便能够操作这么些因秋天点,最终在须求的时候插入到
document 中一定岗位便足以了。

Template 相关的事物非常少,而且它未来早正是纳入生效的
专门的学问文书档案
中了。

我们接下去看注重磅的 Shadow DOM。

Shadow DOM

概述

Shadow DOM
好像提出好久了,最本质的必要是索要一个隔开组件代码功用域的事物,举例小编组件代码的
CSS 不能够影响其余零件之类的,而 iframe 又太重并且可能有各个奇异难点。

可以这么说,Shadow DOM
意在提供一种越来越好地协会页面成分的方法,来为日益复杂的页面使用提供庞大支撑,避免代码间的互相影响。

看下在 chrome 它会是哪些的:

图片 1

我们得以经过 createShadowRoot()前者组件化这些宗旨相关的剧情早就火了很久很久。 来给一个因早秋点成立 Shadow
Root,那些因素类型必须是上面列表的中间八个,不然会抛出 NotSupportedError
分外。

  • 自定义的要素
  • article
  • aside
  • blockquote
  • body
  • div
  • header, footer
  • h1, h2, h3, h4, h5, h6
  • nav
  • p
  • section
  • span

createShadowRoot() 是以往 chrome 达成的
API,来自文书档案:前者组件化这些宗旨相关的剧情早就火了很久很久。https://www.w3.org/TR/2014/WD…。最新的文档API 已经调节为 attachShadow()

归来的 Shadow Root 对象从 DocumentFragment
传承而来,所以能够使用相关的部分方法,举例shadowRoot.getElementById('id')
来获取 Shadow DOM 里边的因素。

简简单单的运用如下:

JavaScript

const div = document.getElementById(‘id’) const shadowRoot =
div.createShadowRoot() const span = document.createElement(‘span’)
span.textContent = ‘hello world’ shadowRoot.appendChild(span)

1
2
3
4
5
6
const div = document.getElementById(‘id’)
const shadowRoot = div.createShadowRoot()
const span = document.createElement(‘span’)
 
span.textContent = ‘hello world’
shadowRoot.appendChild(span)

在此处,笔者把那一个 div 成为是其一 Shadow DOM 的
宿主成分,上边的源委会持续使用这几个名字为。

Shadow DOM 本人就为了代码隔开分离而生,所以在 document 上选取 query
时,是可望而不可及获取到 Shadow DOM 里边的成分的,必要在 Shadow Root 上做 query
才行。

在此间附上三个文书档案,里边有详尽的关于新的行业内部和后日 blink 引擎实现的
Shadow DOM 的界别,官方上称之为 v0 和 v1:Shadow DOM v1 in
Blink。

API

Shadow Root 除了从 DocumentFragment
传承而来的质量和措施外,还多了别的两脾特性:

  • host 只读属性,用来获得那一个 Shadow Root 所属的要素
  • innerHTML 用来赢得可能安装里边的 HTML 字符串,和我们常用的
    element.innerHTML 是一样的

其余,在新型的标准文书档案中,成分除了上边提到的 attachShadow
方法之外,还多了多个属性:

  • assignedSlot 只读,这些因素如若被分配到了某些 Shadow DOM 里边的
    slot,那么会回到那一个相应的 slot 成分
  • slot 成分的 slot 属性,用来钦定 slot 的名号
  • shadowRoot 只读,成分下面对应的 Shadow Root 对象

slot 是什么样?接着看上边包车型客车原委,看完下一节的末梢一片段就能理解上述内容和
slot 相关的三个 API 有怎么样效益。

slot

slot
提供了在动用自定义标签的时候能够传递子模板给到里面采纳的力量,能够轻巧看下
Vue 的贰个事例。

大家先来看下今后 chrome 能够跑的 v0 版本,那二个本子是提供了二个 content
标签,代表了三个占位符,并且有一个 select 属性用来钦点使用什么子成分。

XHTML

<!– component input-toggle template –> <input
type=”checkbox”></input> <content
select=”.span”></content>

1
2
3
<!– component input-toggle template –>
<input type="checkbox"></input>
<content select=".span"></content>

自定义的因素里边的子成分代码是那样的:

XHTML

<input-toggle name=”hello”> <span>hello</span>
<span class=”span”>test</span> </input-toggle>

1
2
3
4
<input-toggle name="hello">
  <span>hello</span>
  <span class="span">test</span>
</input-toggle>

那么显示的结果会和底下的代码是平等的:

XHTML

<input-toggle name=”hello”> <input
type=”checkbox”></input> <span
class=”span”>test</span> </input-toggle>

1
2
3
4
<input-toggle name="hello">
  <input type="checkbox"></input>
  <span class="span">test</span>
</input-toggle>

此间只是说展现结实,实际上,input-toggle 里边应该是开创了三个 Shadow
DOM,然后 content 标签引用了对象的 span 内容,在 chrome 看是那样的:

图片 2

下一场,是风靡规范中的 slot 使用办法,直接上例子代码:

XHTML

<!– component input-toggle template –> <input
type=”checkbox”></input> <slot name=”text”></slot>

1
2
3
<!– component input-toggle template –>
<input type="checkbox"></input>
<slot name="text"></slot>

在自定义的要素标签是如此使用 slot 的:

XHTML

<input-toggle name=”hello”> <input
type=”checkbox”></input> <span class=”span”
slot=”text”>test</span> </input-toggle>

1
2
3
4
<input-toggle name="hello">
  <input type="checkbox"></input>
  <span class="span" slot="text">test</span>
</input-toggle>

通过 slot="text" 的性质来让要素内部的 slot
占位符能够引用到那几个因素,多少个要素选取那么些天性也是足以的。这标准大家便享有了应用标签是从外部传
template 给到自定义成分的里边去行使,而且全体内定放在那里的本领。

CSS 相关

因为有 Shadow DOM 的存在,所以在 CSS
上又增加了十分多有关的东西,在那之中有些要么属于研讨中的草案,命名之类的恐怕会有转移,上边提起的内容主要缘于文书档案:Shadow
DOM in CSS scoping
1,好多有的在 chrome
是曾经落实的了,风乐趣能够写 demo 试试。

因为 Shadow DOM
不小程度上是为着隔绝样式作用域而诞生的,主文书档案中的样式规则不对 Shadow
DOM 里的子文档生效,子文书档案中的体制规则也不影响外界文书档案。

但不可制止的,在一些场景下,我们需求外表能够调节 Shadow DOM
中样式,如提供叁个零部件给您,有的时候候你会愿意得以自定义它个中的片段体裁,同期,Shadow
DOM
中的代码不常候或许须求能够决定其所属成分的体制,以致,组件内部能够定义上面提到的经过
slot 传递进入的 HTML 的样式。所以呢,是的,CSS
选用器中增多了多少个伪类,大家逐一来看下它们有啥样功用。

在读书上边描述的时候,请留心一下选用器的代码是在怎么着岗位的,Shadow DOM
内部依旧外界。

:host 用于在 Shadow DOM 内部甄选到其宿主元素,当它不是在 Shadow DOM
中使用时,便相称不到跋扈元素。

在 Shadow DOM 中的 * 采取器是心有余而力不足取舍到其宿主成分的。

:host( <selector> )
括号中是一个选拔器,那几个能够知晓为是三个用于包容在主文档和 Shadow DOM
中使用的办法,当以此接纳器在 Shadow DOM
中时,会协作到括号中选择器对应的宿主成分,要是还是不是,则相配括号中接纳器能够包容到的要素。

文书档案中提供了贰个例子:

XHTML

<x-foo class=”foo”> <“shadow tree”> <div
class=”foo”>…</div> </> </x-foo>

1
2
3
4
5
<x-foo class="foo">
  <"shadow tree">
    <div class="foo">…</div>
  </>
</x-foo>

在这个 shadow tree 内部的体裁代码中,会有诸如此类的结果:

  • :host 匹配 <x-foo> 元素
  • x-foo 相称不到成分
  • .foo 只相配到 <div> 元素
  • .foo:host 相配不到成分
  • :host(.foo) 匹配 <x-foo> 元素

:host-context( <selector> ),用于在 Shadow DOM
中来检查评定宿主成分的父级成分,假若宿主成分只怕其祖先成分能够被括号中的选取器匹配到的话,那么那几个伪类选择器便相称到那么些Shadow DOM
的宿主成分。个人知道是用来在宿主成拾贰分界因素满意一定的规则时加上样式。

::shadow 那么些伪类用于在 Shadow DOM 外界相配个中间的要素,而 /deep/
那一个标记也是有同样的效用,我们来看多少个例子:

XHTML

<x-foo> <“shadow tree”> <div> <span
id=”not-top”>…</span> </div> <span
id=”top”>…</span> </> </x-foo>

1
2
3
4
5
6
7
8
<x-foo>
   <"shadow tree">
     <div>
       <span id="not-top">…</span>
     </div>
     <span id="top">…</span>
   </>
</x-foo>

对于上述这一段代码的 HTML 结构,在 Shadow DOM
外界的体制代码中,会是那般的:

  • x-foo::shadow > span 能够协作到 #top 元素
  • #top 相称不到成分
  • x-foo /deep/ span 能够包容到 #not-top#top 元素

/deep/ 这几个标记的功力和我们的 >
选取器有一些类似,只不过它是相称其对应的 Shadow DOM
内部的,那一个标记恐怕还或许会生成,举例改成 >> 或者 >>>
之类的,个人以为, >> 会更舒心。

终极三个,用于在 Shadow DOM 内部调治 slot
的样式,在自家查看的那么些文书档案中,一时是以 chrome 达成的为准,使用
::content 伪类,不清除有革新为 ::slot
的大概性。我们看三个事例来通晓一下,固然名称调度了也是大半的用法:

XHTML

<x-foo> <div id=”one” class=”foo”>…</div> <div
id=”two”>…</div> <div id=”three” class=”foo”> <div
id=”four”>…</div> </div> <“shadow tree”> <div
id=”five”>…</div> <div id=”six”>…</div>
<content select=”.foo”></content> </”shadow tree”>
</x-foo>

1
2
3
4
5
6
7
8
9
10
11
12
<x-foo>
  <div id="one" class="foo">…</div>
  <div id="two">…</div>
  <div id="three" class="foo">
    <div id="four">…</div>
  </div>
  <"shadow tree">
    <div id="five">…</div>
    <div id="six">…</div>
    <content select=".foo"></content>
  </"shadow tree">
</x-foo>

在 Shadow DOM 内部的样式代码中,::content div 能够相称到
#one#three#four,留意一下 #two
为何没被相配到,因为它从不被 content
成分选中,即不会开始展览引用。若是改造到 slot 的 name 引用的格局亦是同理。

层叠规则,按照这一个文书档案的布道,对于八个优先等第一样的 CSS 申明,未有带
!important 的,在 Shadow DOM 外界证明的开始时期级高于在 Shadow DOM
内部的,而带有 !important
的,则相反。个人认为,那是提要求外界自然的调节技艺,同一时候让里面可以界定一定的震慑范围。

继续方面绝对轻松,在 Shadow DOM 内部的头号成分样式从宿主成分承接而来。

于今,Web Components
八个部分介绍截至了,在那之中有一对细节,浏览器达成细节,还只怕有使用上的有个别细节,是未曾聊到的,因为详细记录以来,还有那三个东西,内容好多。当使用进度中反常时方可再度查看规范文档,有机会的话会再通盘那一个稿子。下一部分会把那多个内容结合起来,整体看下
Web Components 是怎么选取的。

Web Components

Web Components 总的来讲是提供一整套完美的包裹机制来把 Web
组件化那些事物规范,每一个框架达成的零部件都统一标准地拓展输入输出,那样能够更加好促进组件的复用。结合下面各种部分的内容,大家结合一齐来看下应该怎么利用那几个专门的学业来贯彻大家的零部件:

JavaScript

<!– components/header.html –> <template id=””>
<style> ::content li { display: inline-block; padding: 20px 10px;
} </style> <content select=”ul”></content>
</template> <script> (function() { const element =
Object.create(HTMLInputElement.prototype) const template =
document.currentScript.ownerDocument.querySelector(‘template’)
element.createdCallback = function() { const shadowRoot =
this.createShadowRoot() const clone =
document.importNode(template.content, true)
shadowRoot.appendChild(clone) this.addEventListener(‘click’,
function(event) { console.log(event.target.textContent) }) }
document.registerElement(‘test-header’, { prototype: element }) })()
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!– components/header.html –>
<template id="">
<style>
::content li {
  display: inline-block;
  padding: 20px 10px;
}
</style>
<content select="ul"></content>
</template>
<script>
(function() {
  const element = Object.create(HTMLInputElement.prototype)
  const template = document.currentScript.ownerDocument.querySelector(‘template’)
 
  element.createdCallback = function() {
    const shadowRoot = this.createShadowRoot()
    const clone = document.importNode(template.content, true)
    shadowRoot.appendChild(clone)
 
    this.addEventListener(‘click’, function(event) {
      console.log(event.target.textContent)
    })
  }
 
  document.registerElement(‘test-header’, { prototype: element })
})()
</script>

那是多少个简单的零部件的事例,用于定义三个
test-header,并且给传递进入的子成分 li
增加了有个别零部件内部的体裁,同期给组件绑定了贰个点击事件,来打字与印刷点击指标的文本内容。

看下怎么着在贰个 HTML 文件中引进并且应用三个组件:

XHTML

<!– index.html –> <!DOCTYPE html> <html>
<head> <meta charset=”utf-8″> <title></title>
<link rel=”import” href=”components/header.html”> </head>
<body> <test-header> <ul> <li>Home</li>
<li>About</li> </ul> </test-header>
</body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!– index.html –>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
 
    <link rel="import" href="components/header.html">
  </head>
  <body>
    <test-header>
      <ul>
        <li>Home</li>
        <li>About</li>
      </ul>
    </test-header>
  </body>
</html>

一个 import<link> 把组件的 HTML
文件引用进来,那样会实行组件中的脚本,来注册三个 test-header
成分,那样子大家便足以在主文书档案中使用这一个成分的标签。

下边包车型客车例证是足以在 chrome 平常运行的。

据此,依据下面轻巧的例子能够见到,各样部分的始末是有机结合在一块,Custom
Elements 提供了自定义成分和标签的力量,template 提供组件模板,import
提供了在 HTML 中创设引进组件的形式,而 Shadow DOM
则管理组件间代码隔绝的主题素材。

只能承认,Web Components
标准的提议化解了有的主题素材,必须交由浏览器去管理的是 Shadow DOM,在并未Shadow DOM
的浏览器上落到实处代码隔开分离的艺术多多少少有弱点。个人本人以为组件化的各种 API
相当不足简洁易用,依然有 getElementById
那些的意味,然则交由逐个类库去简化也得以承受,而 import
作用上没难点,不过加载三个零件时质量难点要么值得一说道,标准大概要求在这几个方面提供更加多给浏览器的教导,举个例子是还是不是有非常的大希望提供一种单一诉求加载多个零部件
HTML 的格局等。

在当今的移动化趋势中,Web Components 不止是 Web
端的难点,越多的开采者期望以 Web
的秘诀去达成移动使用,而多端复用的兑现慢慢是以组件的款型铺开,比如
React Native 和
Weex。所以 Web Components
的行业内部或许会潜移默化到多端开垦 Web 化的八个情势和提高。

末段,再啰嗦一句,Web Components
个人以为如故鹏程发展趋势,所以才有了这几个稿子。

1 赞 4 收藏
评论

图片 3

相关文章