就目前而言,純粹的Web Components在兼容性方面還有着較爲長遠的路,這裏作個記錄總結,以記念本身最近關於Web Components的學習道路。javascript
跟 Web Components 打個啵;html
實例源碼git
個人博客github
Web Components由HTML Import、Template、Custom Element、Shadow DOM四種技術規範。上面的三個文件,是我此次學習的主要參考,其中前兩個教材引領我入門,學習了HTML import、Template、shadowDOM以及custom Element的相關知識;而第三個github上的資源則是一個比較完善的綜合使用web Components實現的一個小例子。這裏,最後,我也會給出本身學習製做的一個彈層的組件小例子。web
做用:HTML Import將外部的html引入,引入的文檔全局有效。其用途有二:一是將整個項目全部的公共的css和js引用都放在一個html頁面裏,須要時直接引用這個html文檔便可;二是將寫好的組件放入一個html文檔中,須要時直接引用這個html文檔;segmentfault
用法: 被引用html頁面不須要操做,引用頁面須要加入link標籤 <link rel="import" href="xxx.html" />
這時被引入的文檔內容只會被主文檔存儲起來,不會顯示在頁面中,須要手動添加到DOM結構中。api
將被引用文檔內容添加到DOM結構中,須要先獲取其link值的import,再經過其得到對應子文檔的DOM結構,將其引入。格式以下:瀏覽器
//子文檔 importSub.html <h1>hello world!</h1> //主文檔 importMain.html <head lang="en"> <link rel="import" href="importSub.html"/> </head> <body> <script> //獲取到子文檔在本文檔對應的引用——即子文檔在本文檔的"代言人"; var s = document.querySelector('link[rel="import"]').import; //獲取子文檔要被插入的DOM; var t = s.querySelector('h1'); //插入到主文檔中; document.body.appendChild(t); </script> </body>
template裏能夠存放html,css,js;
template自己及其內部的css、js、html不會被瀏覽器加載的,包括其中的格式;
引入的時候先獲取到模板,再複製模板的content,將其插入dom結構中;模板的做用在於可重用,每次的使用都須要複製模板的content,插入DOM中;模板的複製能夠採用cloneNode,也能夠採用importNode,推薦importNode;格式爲var x=document.importNode(content,true)
或者var x = content.cloneNode(true)
移除模板 document.querySelector('template').remove();
Template模板所定義的css樣式和js可被外界干擾,封裝性很差,一般多與shadowDOM組合;
格式
<div class="container"></div> <template> <style> span{color:red;} </style> <span>hello</span> <script> console.log(1); </script> </template> <script> //經過模板選擇器獲取到模板,再選擇其內容; var m = document.querySelector('template').content; //兩種克隆模板內容的方法 var s = document.importNode(m,true); // var s = document.importNode(m,true); //將克隆結果插入到dom結構中; document.querySelector('.container').appendChild(s); </script> </body> </html>
shadowDOM,造成一個封閉的空間;將內部的html、css、js與外部隔離,不受干擾。其中,DOM結構中的元素是代言人,被爬蟲爬取,而shadowDOM則是真正的DOM,用於展現內容,不會被爬取。多與template組合使用,使template內的css、js不受外界干擾。
shadowDOM內的模板能夠經過:host{}
來修改其外部容器的css樣式,在外部也能夠經過選擇器::shadow 選擇器擊穿
修改shadowDOM內的css樣式; 優先級依照元素選擇器的優先級進行比較,來決定是否可以修改template內部的樣式;
// 給class爲container的div建立一個shadowDOM; var shadow = document.querySelector('.container').createShadowRoot(); // 獲取模板內容 var content = document.querySelector('template').content; //將模板內容插入到shadowDOM中; shadow.appendChild(content);
做用: customElement容許咱們定製獨有的HTMLElement元素;
生命週期:customElement在其生命週期內提供了四個回調函數createdCallback、attachedCallback、attributeChangedCallback和detachedCallback;
格式
//建立一個自定義DOM元素,繼承自HTML.prototype; var MyButton = Object.create(HTMLElement.prototype); //增長自定義方法 MyButton.say = function(){ console.log('hello'); }; //增長生命週期方法 MyButton.createdCallback = function(){ this.innerHTML = 'hello,I\'m customElement!' } //將建立的DOM元素註冊到DOM結構;這裏的註冊名字必須是帶 '-'的寫法;返回一個構造函數; var myButton = document.registerElement('my-button',{ prototype:MyButton, extends:'div', //不加extends屬性則爲 <my-button></my-button>格式,加extends則爲<div is="my-button"></div>格式 }); //接下來能夠什麼也不寫,直接在頁面中建立<div is="my-button"></div>;也能夠執行下面的方法,自動添加; var meButton =new myButton(); document.body.appendChild(meButton); //獲取加入的me-button var s = document.querySelector('div[is="me-button"]'); s.say(); //output:hello;
我理解的Web Components開發組件是customElement作外殼,在其中創建shadowDOM,將模板放到shadowDOM中,造成一個html頁面,使用時經過HTML Import引入。
學習Web Components碰到最多問題是事件方面,不少問題都是因爲真正的DOM結構裏沒有對應的元素,能夠在元素被插入到DOM結構中再綁定事件,引覺得戒!
在學習web Components的時候,想像着本身封裝的一個個組件,將整個頁面經過組件像"搭積木"同樣搭起來,挺有意思!