组件是 Web 开发的方向,现在的热点是 JavaScript 组件,但是 HTML 组件未来可能更有希望。
本文就介绍 HTML 组件的基础知识:自定义元素(custom elements)。
文章结尾还有一则 React 培训消息(含 React Native),欢迎关注。
一、浏览器处理
我们一般都使用标准的 HTML 元素。
<p>Hello World</p>
上面代码中,<p>
就是标准的 HTML 元素。
如果使用非标准的自定义元素,会有什么结果?
<greeting>Hello World</greeting>
上面代码中,<greeting>
就是非标准元素,浏览器不认识它。这段代码的运行结果是,浏览器照常显示Hello World
,这说明浏览器并没有过滤这个元素。
现在,为自定义元素加上样式。
greeting { display: block; font-size: 36px; color: red; }
运行结果如下。
接着,使用脚本操作这个元素。
function customTag(tagName, fn){ Array .from(document.getElementsByTagName(tagName)) .forEach(fn); } function greetingHandler(element) { element.innerHTML = '你好,世界'; } customTag('greeting', greetingHandler);
运行结果如下。
这说明,浏览器对待自定义元素,就像对待标准元素一样,只是没有默认的样式和行为。这种处理方式是写入 HTML5 标准的。
"User agents must treat elements and attributes that they do not understand as semantically neutral; leaving them in the DOM (for DOM processors), and styling them according to CSS (for CSS processors), but not inferring any meaning from them."
上面这段话的意思是,浏览器必须将自定义元素保留在 DOM 之中,但不会任何语义。除此之外,自定义元素与标准元素都一致。
事实上,浏览器提供了一个HTMLUnknownElement
对象,所有自定义元素都是该对象的实例。
var tabs = document.createElement('tabs'); tabs instanceof HTMLUnknownElement // true tabs instanceof HTMLElement // true
上面代码中,tabs
是一个自定义元素,同时继承了HTMLUnknownElement
和HTMLElement
接口。
二、HTML import
有了自定义元素,就可以写出语义性非常好的 HTML 代码。
<share-buttons> <social-button type="weibo"> <a href="...">微博</a> </social-button> <social-button type="weixin"> <a href="...">微信</a> </social-button> </share-buttons>
上面的代码,一眼就能看出语义。
如果将<share-buttons>
元素的样式与脚本,封装在一个 HTML 文件share-buttons.html
之中,这个元素就可以复用了。
使用的时候,先引入share-buttons.html
。
<link rel="import" href="share-buttons.html">
然后,就可以在网页中使用<share-buttons>
了。
<article> <h1>Title</h1> <share-buttons/> ... ... </article>
HTML imports 的更多用法可以参考教程(1,2)。目前只有 Chrome 浏览器支持这个语法。
三、Custom Elements 标准
HTML5 标准规定了自定义元素是合法的。然后,W3C 就为自定义元素制定了一个单独的 Custom Elements 标准。
它与其他三个标准放在一起---- HTML Imports,HTML Template、Shadow DOM----统称为 Web Components 规范。目前,这个规范只有 Chrome 浏览器支持。
Custom Elements 标准对自定义元素的名字做了限制。
"自定义元素的名字必须包含一个破折号(
-
)所以<x-tags>
、<my-element>
和<my-awesome-app>
都是正确的名字,而<tabs>
和<foo_bar>
是不正确的。这样的限制使得 HTML 解析器可以分辨那些是标准元素,哪些是自定义元素。"
注意,一旦名字之中使用了破折号,自定义元素就不是HTMLUnknownElement
的实例了。
var xTabs = document.createElement('x-tabs'); xTabs instanceof HTMLUnknownElement // false xTabs instanceof HTMLElement // true
Custom Elements 标准规定了,自定义元素的定义可以使用 ES6 的class
语法。
// 定义一个 <my-element></my-element> class MyElement extends HTMLElement {...} window.customElements.define('my-element', MyElement);
上面代码中,原生的window.customElements
对象的define
方法用来定义 Custom Element。该方法接受两个参数,第一个参数是自定义元素的名字,第二个参数是一个 ES6 的class
。
这个class
使用get
和set
方法定义 Custom Element 的某个属性。
class MyElement extends HTMLElement { get content() { return this.getAttribute('content'); } set content(val) { this.setAttribute('content', val); } }
有了这个定义,网页之中就可以插入<my-element>
了。
<my-element content="Custom Element"> Hello </my-element>
处理脚本如下。
function customTag(tagName, fn){ Array .from(document.getElementsByTagName(tagName)) .forEach(fn); } function myElementHandler(element) { element.textConent = element.content; } customTag('my-element', myElementHandler);
运行结果如下。
ES6 Class 的一个好处是,可以很容易地写出继承类。
class MyNewElement extends MyElement { // ... } customElements.define('my-new-element', MyNewElement);
今天的教程就到这里,更多用法请参考谷歌的官方教程。
四、参考链接
- John Negoita, Extending HTML by Creating Custom Tags
- StackOverflow, Are custom elements valid HTML5?
- Eric Bidelman, Custom Elements v1: Reusable Web Components
(正文完)
==============================
下面是一则培训消息。
自从我写了《React 技术栈系列教程》以后,有两种反馈:一种是觉得内容不够完整深入,希望有更详细的介绍,另一种是要求补上 React Native。对此我也没办法,精力有限,无法持续投入,只能推荐大家自己去看官方文档。
昨天,优达学城的朋友联系我。他们与 React Training 合作,正式推出了 React 培训课程,希望我帮忙推广。
我听了很兴奋,因为 React Training 是美国最专业的 React 培训机构,水平很高。几个讲课老师在 React 社区都非常有名,React Router 、unpkg 和 mustache.js 就是他们的作品。我相信,国内很难找到这样水平的老师和课程。
实际上,这件事在美国也很受关注,Techcrunch 进行了报道。
整个课程与美国完全同步,一共持续4个月,分成三个环节。
课程内容涉及整个 React 技术栈,PC 端和手机端并重。学完之后,可以获得纳米学位的证书。
课程价格是 3399 元人民币。注意,该课程不是零基础的,要求学习者已经掌握 JavaScript 基本语法,所以有报名审核环节。
想学 React/React Native 的同学可以考虑一下,点击这里了解详情,报名到6月27日截止。
(完)
boomyao 说:
已经自学react一年了,也可以用react开发个人博客等网站,请问再花3000学习这门课程值吗?
2017年6月22日 15:00 | # | 引用
阮一峰 说:
@boomyao:他们好像有试听的。你咨询一下。
2017年6月22日 16:13 | # | 引用
李帅武 说:
我参与公司的reactnative开发,当时自学半个月就上手了。。而卧对于react却一窍不通。。
2017年6月22日 16:16 | # | 引用
业余草 说:
我已自学成才了,跟着阮老师就行了,实惠还免费!
钱我真的没有!穷的只剩内裤了!
2017年6月22日 16:51 | # | 引用
CODE大全 说:
我想说的是这个证书,国家认吗?BAT认吗?
2017年6月22日 16:52 | # | 引用
shenjunjian 说:
赶快顶一个,这技术是未来的希望
。。。。。。。呜呜,好像这么多年一直活在希望里了
2017年6月22日 23:32 | # | 引用
shenjunjian 说:
顶的太快了,看完才发现内容不完整,如何自定义组件,shadow之类没讲,是不是还没写完呀!
2017年6月22日 23:36 | # | 引用
李金珂 说:
感觉有点写起来有点像angular 哈~
2017年6月23日 10:20 | # | 引用
小胖子 说:
vue ag jq bs ......................学不完的前端框架真的,人的精力有限哎,真的要跟罗胖说的那样终身学习?可能对大部分学习能力一般前端也算是一种筛选。
2017年6月23日 17:40 | # | 引用
L 说:
你好,一直在读你的文章。刚刚发现你的网站首页源码里面好多duchang,seqing的乱七八糟的东西,是你自己放的吗?还是有人故意搞得。你看下
2017年6月23日 18:42 | # | 引用
harry 说:
不值
2017年6月23日 19:00 | # | 引用
阮一峰 说:
@L:
网站有安全漏洞,被注入代码了。
2017年6月23日 21:35 | # | 引用
bigglesworth 说:
额,bat旗下的有认证的公司,你可以去优达学城看。
2017年6月24日 23:35 | # | 引用
一枚小白 说:
你好,我大专计算机专业,想自学web前端 数学英语不太好,是否合适学习web前端呢?尤其是 JS 。希望大神回复我!
2017年6月25日 20:21 | # | 引用
cshenger 说:
自打做了前端这行发现80%的时间都在学习,就20%的时间在干活^_^
2017年6月26日 15:42 | # | 引用
蒋泽涌 说:
= =。老师你为啥不来信管任教。跑国贸学院去。你觉得张高煜老师的技术水平怎么样?
2017年6月26日 16:08 | # | 引用
杜宁 说:
2017年6月26日 18:18 | # | 引用
xubiao 说:
楼主用的什么编辑器啊,文章中图片样式怎么做的?
2017年6月28日 23:34 | # | 引用
呼呼哈哈 说:
本来就是XML呀。。。。。
2017年6月30日 13:27 | # | 引用
詹子镇 说:
你的第三版es6入门快出了吗
2017年7月 7日 11:40 | # | 引用
晴朗哥 说:
如果因为还过得去的话,直接看官方文档就好,没有必要去培训班。
2017年7月21日 16:07 | # | 引用
swing 说:
阮老师研究过polymer吗?
2017年7月21日 20:33 | # | 引用
网络周星星 说:
数学英语不好没关系,关键逻辑条例清晰就行,js讲的就是逻辑,剩下的就是语法结构了,想学就试试,试了才知道,问谁都没用的
2017年9月25日 14:12 | # | 引用
aaa 说:
数学英语不好没关系,关键逻辑条例清晰就行,js讲的就是逻辑,剩下的就是语法结构了,
试了才知道,问谁都没用的
2022年5月13日 01:31 | # | 引用