Web Components之Custom Elements

什麼是Web Component?

Web Components 包含了多種不一樣的技術。你能夠把Web Components當作是用一系列的Web技術建立的、可重用的用戶界面組件的統稱。Web Components使開發人員擁有擴展瀏覽器標籤的能力,能夠自由的進行定製組件。但截至本文時間,Web Components依然是W3C工做組的一個草案,併爲被正式歸入標準,但這並不妨礙咱們去學習它。web

Web組件

何爲Web組件?Web組件相對於Web開發者來講並不陌生,Web組件是一套封裝好的HTML,CSS,以及JavaScript,它最大的特色就是可複用。基本在每個網站上咱們均可以看到各式各樣的組件,例以下拉菜單、按鈕、圖片滾播、日曆控件等。慢着,既然咱們已經能夠實現web組件的封裝,那Web Component這傢伙出現的意義是什麼呢?Web Component回答道:「大家的實現方式不夠優雅也不夠完美,仍是看看個人吧」。編程

由於當咱們使用各類編程技巧對組件進行封裝時,一個沒法規避的事實是,組件的內部是可被訪問和影響的,例如咱們對樣式表進行改動時常常會擔憂影響到頁面組件的樣式。而經過Web Component封裝出來的組件,咱們能夠選擇讓組件的內部隱藏起來,也就是說,組件內部是與世隔絕的!瀏覽器

Web Component的組成

  • Custom Elements
  • HTML Templates
  • Shadow Dom
  • HTML Imports

總的來講,Web Components包含以上四種技術,本文着重談談Custom Element,這也是Web component中最核心的部分。app

Custom Elements

自定義元素是一個可由建立者來自定義接口的對象。在建立時咱們須要經過 document.registerElement() 來對自定義元素進行註冊。該方法會返回一個元素的構造器,經過該構造器咱們就能夠建立咱們的自定義元素的實例了。dom

var MyButton= document.registerElement('my-button');
document.body.appendChild(new MyButton());

實際上 document.registerElement(tag-name, prototype) 包含兩個參數:函數

tag-name: 自定義元素的標籤名,這個標籤名必須包含連字符'-',這樣作的母的是用以區分自定義元素和HTML規範的元素學習

prototype: 這是一個可選的參數,用於描述該元素的原型,在該元素中你能夠爲自定義元素進行接口的定義網站

var MyElement = document.registerElement('my-element', { 
  prototype: Object.create(HTMLElement.prototype, { 
    createdCallback: { 
      value: function() { 
        this.innerHTML = "<p>I'm a Custom Element</p>";
      } 
    } 
  }) 
});
document.body.appendChild(new MyElement())

在上面的例子中,咱們經過Object.create()方法建立了一個繼承自HTMLElement的對象做爲自定義對象的原型,並設置了元素默認的 innerHTML ,若是你對Object.create()方法的第二個參數不熟悉,你最好先去查閱一下。實際上它的上面的例子跟下面給出的寫法的效果是同樣的:this

var MyElementProto = Object.create(HTMLElement.prototype)

MyElementProto.createdCallback = function() {
    this.innerHTML = "<p>I'm a Custom Element</p>"
}

var MyElement = document.registerElement('my-element', { prototype: MyElementProto })

document.body.appendChild(new MyElement())

接着,在頁面上咱們能夠看到渲染出以下結構:spa

自定義元素的生命週期

在上面的例子中咱們能夠看到自定義元素的原型上有一個 createdCallback 屬性,它的值是一個回調函數,在自定義元素被建立的時候被調用。實際上自定義元素在它的生命週期中可能會經歷如下幾種變化:

  • 自定義元素在其註冊前被建立
  • 自定義元素被註冊
  • 自定義元素的實例在自定義元素註冊後被建立
  • 自定義元素被插入到文檔中
  • 自定義元素從文檔中移除
  • 自定義元素的屬性被建立、移除、修改

在自定義元素經歷上面某些變化時,不一樣的回調函數會被調用。這些回調函數被保存在一個名爲生命週期回調的鍵值對集合中。咱們可實現的回調函數總共有如下4種,其中 attributeChangedCallback 的回調函數中咱們能夠經過其參數訪問到操做的屬性名、老的屬性值、新的屬性值。

DOM:

<div id="modify">
  <label class="CEgreen"><input type="radio" name="CEclass" value="green">green box</label>
  <label class="CEred"><input type="radio" name="CEclass" value="red">red box</label>
</div>

JS:

var MyElement = document.registerElement('my-element', { 
  prototype: Object.create(HTMLElement.prototype, { 
    createdCallback: { 
      value: function() {
        this.innerHTML = "<span>I'm a Custom Element</span>"
      }
    },
    attributeChangedCallback: {
      value: function(property, oldValue, newValue) {
        this.innerHTML = "attribute '" + property + "' is modified to " + newValue
      }
    }
  }) 
})
document.body.appendChild(new MyElement())

var temp = document.querySelector("#modify")
var myElement = document.querySelector("my-element")

temp.addEventListener('click', function(e){
  console.log(e.target.value)
  myElement.className = e.target.value
})

 

另外,給自定義元素添加樣式和普通元素是同樣的,這是上面例子中爲自定義元素添加的樣式:

my-element {display: inline-block;margin-top: 20px;padding: 10px;font-size: 24px;}

這就是一個最基礎的自定義元素的實現了。若是咱們但願自定義元素內部不受外部樣式的影響,咱們須要使用Shadow Dom來對內部dom結構和樣式進行封裝。

相關文章
相關標籤/搜索