说说HTML自定义元素
发布在每天学点javascript2014年3月9日view:10797
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

enter image description here

说说HTML自定义元素

最近一段时间,你可能已经听到了不少关于Web Components的消息,有人甚至传言它将彻底改变web开发的方式。如果你还没有听说过,那么你就有点孤陋寡闻了。

Web Components是一系列相关联的技术,它只在使web元素在整个web中使用。虽然Shadow DOM是一个好东西,但是最具有移植性的技术还是自定义元素,它能够让你定义自己的元素,包括它们的行为和属性。

这听起来实在是一个太酷的描述了,在本文中我们将会对自定义元素展开详细的介绍,包括它们为何具有移植性以及如何使用它们。

自定义元素的目的是什么?

基本的思想是如果你创建了一个元素,它总是扮演同样的角色并且可以在它上面运用相同的属性和函数,那么你就应该在定义完成之后将它命名。我们有video元素可以用来播放视频,select元素可以用来展示选择盒子,img元素可以用来展示图片。很多元素都能够描述它们自己的功能。

但是今天的web比以前的web要复杂得多,但是HTML不能总是发生变化。因此自定义元素将会赋予开发者很高的灵活性,让他们可以基于所需的功能来创建元素并让我们可以自定义属性。

如果我们创建的元素非常稳定,它们可以变成HTML标准的一个标准元素。我们现在所做的事情也许就能决定HTML的未来。

我们现在就可以在HTML中自定义元素吗?

完全可以!同时,自定义元素也非常简单。现在就打开你最喜欢的文本编辑器,在一个HTML文档中编写一个自定义元素,如下所示:

<apes>...</apes>  

将这个HTML文件在浏览器中打开。你会发现它能够正常运行。你可以为它添加样式,在上面绑定JavaScript事件。也许它并不是“合法的”(不过如今还有谁会关心这种事呢?不是吗?),但是它能够正常运行。你可以为它添加任何你喜欢的名字,它将会创造一个新的行内元素。

的确,你可以像上面这样做,也许它也可以将你的标记变得稍微可以理解 – 但是实际上这是它带来的唯一好处。自定义元素要比上面例子中定义的这个元素聪明得多,它能够带来真正的,可以衡量的好处。我们马上就会看到自定义元素带来的好处:首先,我们会展示编写一个自定义元素是如此的简单。

创建一个自定义元素难不难?

正如上一节的最后一句话一样,创建一个自定义元素非常简单。第一步,你需要想一个好名字。在这里唯一的标准就是不要和当前已经存在的元素起冲突,以及你必须在名字的中间使用一个连字符。例如:

<great-apes>...</great-apes>  

如果你已经想好了一个名字,下一步就是在DOM中注册这个元素,你只需要使用JavaScript中的registerElement()方法,如下所示:

document.registerElement('great-apes');  

现在DOM就能够识别出你新注册的great-apes元素,真正的好戏才刚刚开始。顺便要提到的一点是,像这样没有在HTML标准中定义的元素叫做“自定义标签”,所以当你看到有人使用它的时候也不要决定惊讶。

但是目前还是没有什么有意思的东西

不要着急,我们接着往下讲。伪自定义元素(就像是前面提到的<apes>)和真正的自定义元素之间的差别在于有没有使用DOM暴露的接口。没有注册的自定义元素,使用的是HTMLUnknownElement接口,而经过注册的自定义元素使用的则是HTMLElement接口。

二者有什么区别?利用HTMLElement接口,我们可以添加我们自己的方法和属性,从而在本质上创建一个元素的API。在这里你看到元素的API或许会感到惊讶,但是没错,每一个元素都有它自己的API。

为了做到这一点,你首先需要定义一个新的原型对象,然后将你的属性和方法绑定到上。在这里的例子中,我们将创建一个叫做hoot()的方法用来将一条消息打印到控制台上:

var apeProto = Object.create(HTMLElement.prototype);
apeProto.hoot = function() {
    console.log('Apes are great!');
}  

下一个步骤是注册这个元素,就像前面提到的那样那样。只是这一次我们需要添加一个可选元素来说明我们定义的元素需要使用一个新的自定义原型:

document.registerElement('great-apes', {prototype: apeProto});

完成了上面的步骤之后,你就可以在DOM中查询你的元素了并且调用它的方法:

var apes = document.querySelector('great-apes');
apes.hoot();  

上面的例子是最简单的例子,但是我们可以来花一分钟考虑一下如何将这个例子进行扩展:添加一些独有的属性,性质以及事件;将这个标签放到你的元素中来和属性值一起进行渲染;甚至是创建一个元素,它没有任何的UI,但是可以执行一些功能例如数据库查询。事实上,我们可以做很多事情。

如果你想要看一看一个自定义元素能够做什么,你可以搜索一下<google-maps>元素,它将会把一个谷歌地图连同一些选项嵌入到页面中,比如下面的代码:

<google-maps latitude="-8.034881" longitude="-34.918377"></google-maps>

已经存在的元素可能使用这个API进行扩展吗?

确实,很多人都很关心这个问题。问题的答案是yes,我们可以使用自定义元素来扩展已经存在的元素。我们可以为已经存在的元素创建一个全新的API。这听起来确实有些不可思议,但是它是事实。

下面的例子中,我们将创建一个表格,并且将我们的hoot()方法绑定在上面。为了完成这件事,我们将遵循上面例子中的步骤,唯一需要改变的是在registerElement中添加一些选项:

document.registerElement('great-apes', {
    prototype: apeProto,
    extends: 'table'
});  

extends参数的值告诉DOM,这个自定义元素是用来扩展table元素的。现在,我们来编写一个自定义table元素,并且通知DOM它想要被扩展,我们使用is属性:

<table is="great-apes">…</table>

普通的table元素现在就已经拥有了它自己的API。例如,它可以使用一个标准的接口查询它自己的数据。一个表格可以有接口来查询自己的数据!!!还有什么比这个更令人激动的吗?

如果你想看看现实中已经实现的扩展元素,你应该看一看video-camera元素,它扩展了video元素,让它可以使用getUserMedia()来进行动态输入:

<video is="video-camera"></video>

它确实很酷,还有其他的吗?

一系列的回调事件将会在自定义元素的生命周期中北触发:当一个元素被创建时(createCallback),绑定到DOM上时(attachedCallback)或者从一个DOM上解绑时(deachedCallback),或者当一个属性变化时(attributeChangeCallback)。例如,为了在每次创建一个新元素时都运行一个匿名函数,你可以使用下面的代码:

apeProto.createdCallback = function () {…};

自定义元素和其他的web组件能够一起运行吗?

自定义元素完全可以和其他组件一起使用。例如,你可以在标签中包含template元素,它不会被浏览器所解析,直到这个元素被初始化:

<great-apes>
    <template>…</template>
</great-apes>  

你可以确保内部的代码被封装好与浏览器隔开,同时在用户使用Shadow DOM时隐藏。同时可以通过使用HTML imports来跨文件和网站分享你的元素。

如果你还不熟悉上面提到的其他技术,只需要记住一点即可:自定义元素能够完美的和其他元素一起运行。

我现在就能使用自定义元素吗?

答案是否定的,同时也是肯定的。自定义元素是一个很新的概念,浏览器厂商已经在努力将它们添加进浏览器中,最新版本的Chrome和Opera浏览器已经实现了registerElement()方法,它也将会登陆最新的Firefox Nightly。但是,自定义元素还不足以使用在生产环境中。

但是,我们还有另一种选择,就是使用Polymer。如果你没有听说过Polymer,它其实是一个开源的项目,目的是让我们现在就可以使用未来的web技术,它包含Web Components以及自定义元素。Polymer是一个开发库,它在内部实现了那些旧版本浏览器不支持的方法,它同时也是一个UI库,你可以使用其中普通的元素和模式来创建UI。

如果你对自定义元素感兴趣的话,Polymer是你最好的选择。

可访问性怎么样?

使用自定义元素有一个最大的缺点就是:我们需要JavaScript。如果没有JavaScript,你的新元素将不会运行,同时会退回到一个普通的HTMLUnknownElement。除非你的元素被浏览器本身所采用,除此之外没有其他简单的方法。在你编写自定义元素的时候,你就应该准备好一个后备方案,同时也应该处理好JavaScript。

另外,我们强烈的推荐你在自定义元素中添加ARIA角色和属性,就像是如今的浏览器默认标签一样,它可以确保每一个人都获得同样的体验。


本文译自A Detailed Introduction To Custom Elements,原文地址http://coding.smashingmagazine.com/2014/03/04/introduction-to-custom-elements/

如果你觉得本文对你有帮助,请为我提供赞助 https://me.alipay.com/jabez128

评论
发表评论
暂无评论
WRITTEN BY
张小俊128
Intern in Baidu mobile search department。认真工作,努力钻研,期待未来更多可能。
TA的新浪微博
PUBLISHED IN
每天学点javascript

javascript进阶级教程,循序渐进掌握javascript

我的收藏