You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
可以看到上面比较详细而又不详尽的介绍了 Web Component 的相关知识,鉴于 Web Component 的兼容性及流行度,可能大家目前并不会实际使用在项目里(虽然有一些 polyfill, 比如 Polymer),只是想稍作了解,掌握 Web 的开发方向,所以这篇文章就是帮助大家快速理解其中的核心概念。我这里仅仅是抛砖引玉,如果大家有兴趣继续深入研究里面的每个 API 的话可以再去 MDN 上看看文档和相关的规范。
The text was updated successfully, but these errors were encountered:
luokuning
changed the title
[Web Component] 之 自定义元素
[Web Component] 之自定义元素
Aug 15, 2017
前言
Shadow DOM
或多或少在工作当中会有这样的体验:
id
名时总要小心翼翼的,生怕一不留神就重复了,导致一些难以追踪的问题出现。class
名也是一样的,当单个页面变得很复杂而为了避免重复,本来一个好好的<div class='title'>
很可能就变成了<div class='title-level-2'>
(这个问题其实 css-modules 是个不错的解决方案)。还好有了 Shadow DOM,它也正是封装 Web Component 的关键要素。标准给
HTMLElement
实例添加了一个attachShadow
方法,利用这个方法,我们可以把 Shadow DOM 附加到一个已经存在的 HTML 元素上。ShadowRoot
里的元素会作为实际渲染的元素显示出来,这样p#hostElement
会显示为红色的 Hello World,而且外面的样式不会影响里面的,里面的样式也不会影响外面的元素。Template 标签
浏览器新增了一个
template
标签,写在标签里的任何子元素浏览器都不会去渲染也不会去解析,直到你通过脚本的方式让浏览器去"激活"这部分内容。如果你运行这段代码,最开始浏览器什么都不会有,过两秒后会 alert 一个 123,然后页面才会出现有黑色边框的正方形。这里涉及一个重要的属性,就是
templateElement.content
的属性,它的值是 Document Fragment 类型的对象。其实
template
元素经常会跟slot
标签搭配使用,这个我们待会再讲。自定义元素
直接上代码会好解释很多,自定义元素首先当然需要继承自
HTMLElement
类,constructor
方法是在元素被创建或者更新的时候调用的。我们通过调用attachShadow
方法让 Shadow DOM 附着到自定义元素上。然后又动态创建了一个p
元素,其内容是自定义元素上的data-name
属性值。最后调用customElements.define
方法完成自定义一个 HTML 元素 (不能多次注册同一标记,浏览器了解某一新标签后也不能再撤回了)。另外需要注意标准要求自定义元素名需要有一个连字符,而且使用的时候不能自我封闭,必须编写封闭标签(<x-product></x-product>
)。扩展
HTMLElement
可确保自定义元素继承完整的 DOM API,并且添加到类的任何属性与方法都会成为元素 DOM 接口的一部分。一定需要在
constructor
里调用this.attachShadow
方法吗?当然不是必须的,这里只是稍微演示了一下 Shadow DOM 跟自定义元素结合在一起会发生什么。你可以直接写:这样会直接把
p
标签插入到x-product
元素中,页面的显示效果跟上面是一样的,但是这样就没 Shadow DOM 的优势了。Web Component
上面的代码可以看到我们是手动创建了一个
p
标签,然后插入到shadowRoot
中的,如果有很多元素的话我们不可能每个都手动创建再插入,这个时候就该用到template
标签了。正如我们最开始说的,虽然这些标准可以独立使用,但是结合在一起的话会发挥出更大的作用。下面看一个比较完整的例子:slot
,槽的意思。其作用看代码就很清晰了,它可以有个name
属性及预定义元素。当在自定义元素中有其他子元素时,子元素可以有个slot
属性,表示想匹配替换哪个slot
元素。constructor
方法之外,还可以定义其他几个原型方法,比如这里的connectedCallback
表示当元素被插入到文档中会触发的回调,disconnectedCallback
表示元素从文档中移除时触发的回调等等。HTML 导入(Import)
再想象一个场景:你依照 Web Component 标准开发了一个功能完备又炫酷的组件,恰好这个组件很多人都需要用,难道这个时候大家只能把
template
和你写的脚本都复制粘贴到每个页面里吗?显然这很不优雅,所以 HTML Import 就出现了。
将
link
标签的rel
设置为import
,href
指向的是任意页面元素 (HTML/CSS/JS) 组成的文件,一行简单的代码就能将你的组件导入到页面里。href
当然可以是网络上的 URL,不过其他域的资源需要允许 CORS。如果想引入某个组件到你的页面里,一般来说这么用就够了,但是 HTML Import 所包含的东西却远没这么简单,下面再稍微介绍一些其他的特性。
如果想访问导入的内容,通过
link
元素的import
属性:导入的内容并不在主文档中,仅仅作为主文档的附属存在,但是导入中的脚本会在包含导入文档的
window
上下文中运行。因此你可以将导入中的 HTML 元素或者样式加入到当前文档中。当然如果你的导入文档中已经用
customElements.define
定义了一些组件,那么你无需任何操作就能在页面中使用它们,因为正如上面说的,导入中的脚本会在当前文档中执行。还有一些关于导入的子导入及管理依赖等等其他方面的知识这里就不展开篇幅了。总结
可以看到上面比较详细而又不详尽的介绍了 Web Component 的相关知识,鉴于 Web Component 的兼容性及流行度,可能大家目前并不会实际使用在项目里(虽然有一些 polyfill, 比如 Polymer),只是想稍作了解,掌握 Web 的开发方向,所以这篇文章就是帮助大家快速理解其中的核心概念。我这里仅仅是抛砖引玉,如果大家有兴趣继续深入研究里面的每个 API 的话可以再去 MDN 上看看文档和相关的规范。
The text was updated successfully, but these errors were encountered: