元件是 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日截止。
(完)