Web Components不是單一的規(guī)范,而是一系列的技術(shù)組成,包括Template、Custom Element、Shadow DOM、HTML Import四種技術(shù)規(guī)范。使用時,并不一定這四者都要用到。其中,Custom Element和Shadow DOM最重要,Template和HTML Import只起到輔助作用。
template標(biāo)簽
document.importNode方法用于克隆外部文檔的DOM節(jié)點。
//檢查瀏覽器是否支持
'content' in document.createElement('template');
//模板
<template id="profileTemplate">
<div class="profile">
<img src="" class="profile__img">
</div>
</template>
//使用模板,并且修改模板內(nèi)部內(nèi)容
var template = document.querySelector('#profileTemplate');
template.content.querySelector('.profile__img').src = 'profile.jpg';
Custom Element
HTML預(yù)定義的網(wǎng)頁元素,有時并不符合我們的需要,這時可以自定義網(wǎng)頁元素,這就叫做Custom Element。它是Web component技術(shù)的核心。舉例來說,你可以自定義一個叫做super-button的網(wǎng)頁元素。
//檢查瀏覽器是否支持
'registerElement' in document
//使用自定義元素前,必須用document對象的registerElement方法登記該元素。該方法返回一個自定義元素的構(gòu)造函數(shù)。
var SuperButton = document.registerElement('super-button');
document.body.appendChild(new SuperButton());
//如果想讓自定義元素繼承某種特定的網(wǎng)頁元素,就要指定extends屬性。比如,想讓自定義元素繼承h1元素,需要寫成下面這樣。
var MyElement = document.registerElement('another-heading', {
prototype: Object.create(HTMLElement.prototype),
extends: 'h1'
});
//添加屬性和方法
var XFoo = document.registerElement('x-foo', {
prototype: Object.create(HTMLElement.prototype, {
bar: {
get: function() { return 5; }
},
foo: {
value: function() {
console.log('foo() called');
}
}
})
});
回調(diào)函數(shù):
- createdCallback:實例生成時觸發(fā)
- attachedCallback:實例插入HTML文檔時觸發(fā)
- detachedCallback:實例從HTML文檔移除時觸發(fā)
- attributeChangedCallback(attrName, oldVal, newVal):實例的屬性發(fā)生改變時(添加、移除、更新)觸發(fā)
Shadow DOM
所謂Shadow DOM指的是,瀏覽器將模板、樣式表、屬性、JavaScript代碼等,封裝成一個獨立的DOM元素。外部的設(shè)置無法影響到其內(nèi)部,而內(nèi)部的設(shè)置也不會影響到外部,與瀏覽器處理原生網(wǎng)頁元素(比如<video>元素)的方式很像。Shadow DOM最大的好處有兩個,一是可以向用戶隱藏細(xì)節(jié),直接提供組件,二是可以封裝內(nèi)部樣式表,不會影響到外部。
var shadowRoot = element.createShadowRoot();
document.body.appendChild(shadowRoot);
HTML Import
網(wǎng)頁可以加載外部的樣式表、腳本、圖片、多媒體,卻無法方便地加載其他網(wǎng)頁,iframe和ajax都只能提供部分的解決方案,且有很大的局限。HTML Import就是為了解決加載外部網(wǎng)頁這個問題,而提出來的。
//檢測瀏覽器是否支持
'import' in document.createElement('link');