自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Web Components入門(mén)教程

移動(dòng)開(kāi)發(fā)
今天 ,Web 組件已經(jīng)從本質(zhì)上改變了HTML。初次接觸時(shí),它看起來(lái)像一個(gè)全新的技術(shù)。Web組件最初的目的是使開(kāi)發(fā)人員擁有擴(kuò)展瀏覽器標(biāo)簽的能力,可以自由的進(jìn)行定制組件。

今天 ,Web 組件已經(jīng)從本質(zhì)上改變了HTML。初次接觸時(shí),它看起來(lái)像一個(gè)全新的技術(shù)。Web組件最初的目的是使開(kāi)發(fā)人員擁有擴(kuò)展瀏覽器標(biāo)簽的能力,可以自由的進(jìn)行定制組件。面對(duì)新的技術(shù),你可能會(huì)覺(jué)得無(wú)從下手。那這篇文章將為你揭開(kāi)Web組件神秘的面紗。如果你已經(jīng)熟知HTML標(biāo)簽和DOM編程,已經(jīng)擁有了大量可用 的Web組件,那么你已經(jīng)是Web組件專(zhuān)家了。

Web組件的現(xiàn)狀

隨著各式各樣的用戶(hù)需求,瀏覽器的原生組件已經(jīng)無(wú)法滿足需求。Web組件也就變得越來(lái)越重要。

我們將以自定義一個(gè)傳統(tǒng)三方插件為例來(lái)介紹Web組件。

首先,需要引用插件的CSS和JavaScript資源:

  1. <link rel="stylesheet" type="text/css" href="my-widget.css" /> 
  2.  
  3. <script src="my-widget.js"></script> 

接下來(lái),我們需要向頁(yè)面中添加占位符。

  1. <div data-my-widget></div> 

***,我們需要使用腳本來(lái)找到并且實(shí)例化這個(gè)占位符為Web組件。

  1. // 使用 jQuery 初始化組件 
  2.  
  3. $(function() { 
  4.  
  5.     $('[data-my-widget]').myWidget(); 
  6.  
  7. }); 

通過(guò)以上是三個(gè)基本步驟。已經(jīng)完成了在頁(yè)面中添加了自定義插件,但是瀏覽器無(wú)法確定自定義組件的生命周期,如果通過(guò)以下方式聲明則使自定義組件生命周期變得清晰了。

  1. el.innerHTML = '<div data-my-widget></div>'

因?yàn)檫@不是一個(gè)內(nèi)置的組件,我們現(xiàn)在必須手動(dòng)實(shí)例化新組件,

  1. $(el).find('[data-my-widget]').myWidget(); 

避免這種復(fù)雜設(shè)置方法的有效方式是完全抽象DOM交互。不過(guò),這個(gè)動(dòng)作也比較復(fù)雜,需要?jiǎng)?chuàng)建框架或者庫(kù)來(lái)自定義組件。

面臨的問(wèn)題

組件一旦被聲明,占位符已經(jīng)被替代為原生的HTML標(biāo)記:

  1. <div data-my-widget> 
  2.  
  3. <div class="my-widget-foobar"> 
  4.  
  5. <input type="text" class="my-widget-text" /> 
  6.  
  7. <button class="my-widget-button">Go</button> 
  8.  
  9. </div> 
  10.  
  11. </div> 

這樣做的弊端是,自定義組件的標(biāo)記和普通HTML組件的標(biāo)記混雜在一起,沒(méi)有清晰的分割和封裝。這就不可避免的會(huì)出現(xiàn)命名及樣式等沖突。

Web組件的產(chǎn)生

隨著三方Web組件的發(fā)展,它已經(jīng)成為了Web開(kāi)發(fā)不可或缺的部分:

  1. <!—導(dǎo)入: --> 
  2.  
  3. <link rel="import" href="my-widget.html" /> 
  4.  
  5. <!—使用:--> 
  6.  
  7. <my-widget /> 

在這個(gè)實(shí)例中,我們通過(guò)導(dǎo)入HTML來(lái)添加組件并且立即使用。

更重要的是,因?yàn)?lt;my-widget />是瀏覽器原生支持的組件,它直接掛在瀏覽器的生命周期中,允許我們像添加原生組件一樣添加三方組件。

  1. el.innerHTML = '<my-widget />'
  2.  
  3. // 插件當(dāng)前已經(jīng)被實(shí)例化 

當(dāng)查看這個(gè)組件的HTML 源碼,你會(huì)發(fā)現(xiàn)它僅僅是一個(gè)單一的標(biāo)簽。如果啟用瀏覽器Shadow DOM 特性,才可以查看標(biāo)簽內(nèi)的組件,你將會(huì)發(fā)現(xiàn)一些有趣的事情,

clip_image001[1]

當(dāng)我們談?wù)揥eb組件時(shí),我們不是在談?wù)撘婚T(mén)新技術(shù)。Web組件最初的目的是給我們封裝能力,它可以通過(guò)自定義組件和Shadow DOM 技術(shù)來(lái)實(shí)現(xiàn)。所以,接下來(lái),我們將著重介紹下這兩項(xiàng)技術(shù)。介紹以上兩個(gè)技術(shù)之前,我們***先梳理下已知瀏覽器原生組件。

已知的HTML組件

我們知道組件可以通過(guò)HTML標(biāo)記或JavaScript來(lái)實(shí)例化:

使用標(biāo)記實(shí)例化:

  1. <input type="text" /> 
  2. document.createElement('input'); 
  3. el.innerHTML = '<input type="text" />'

使用JaveScript實(shí)例化:

  1. document.createElement('input')  
  2.  
  3. document.createElement('div'

添加帶有屬性的HTML標(biāo)簽:

  1. // 創(chuàng)建帶有屬性的input標(biāo)簽... 
  2.  
  3. el.innerHTML = '<input type="text" value="foobar" />'
  4.  
  5. //這時(shí)value屬性已經(jīng)同步 
  6.  
  7. el.querySelector('input').value; 

組件可以響應(yīng)屬性的變化:

  1. // 如果我們更改value 屬性值 
  2. input.setAttribute('value', 'Foobar'); 
  3.  
  4. //屬性值會(huì)立即更改 
  5. input.value === 'Foobar'; // true 

組件可以有內(nèi)部隱藏的DOM結(jié)構(gòu):

  1. <!—使用一個(gè)input實(shí)現(xiàn)復(fù)雜的日歷功能--> 
  2. <input type="date" /> 
  3.   
  4.  // 盡管其內(nèi)部結(jié)構(gòu)比較復(fù)雜,但是已經(jīng)封裝成為一個(gè)組件 
  5. dateInput.children.length === 0; // true 

組件可以使用子組件:

  1. <!—可以給組件提供任意個(gè) 'option' 標(biāo)簽--> 
  2.  
  3. <select> 
  4.  
  5. <option>1</option> 
  6.  
  7. <option>2</option> 
  8.  
  9. <option>3</option> 
  10.  
  11. </select> 

組件可以為其子組件提供樣式:

  1. dialog::backdrop { 
  2.  
  3.     background: rgba(0, 0, 0, 0.5); 
  4.  

***,組件可以有內(nèi)置樣式。和自定義插件不同,我們不需要為瀏覽器的原生控件引用CSS文件。

有了以上的了解,我們已經(jīng)具備了解Web組件的基礎(chǔ)。使用自定義組件和Shadow DOM,我們可以在我們的插件中定義所有這些標(biāo)準(zhǔn)行為。

#p#

自定義組件

注冊(cè)一個(gè)新組件也比較簡(jiǎn)單:

  1. // 'document.register' 返回一個(gè)構(gòu)造函器 
  2. var MyElement = document.register('my-element'); 

你也許注意到上面的自定義組件名稱(chēng)包含一個(gè)連接符。這是為了確保自定義組件名稱(chēng)不和瀏覽器內(nèi)置組件不沖突。

現(xiàn)在<my-element />這個(gè)組件具備了原生組件的特性,

所以,自定義組件也同樣可以進(jìn)行普通的DOM操作:

  1. document.create('my-element'); 
  2.  
  3. el.innerHTML = '<my-element />'
  4.  
  5. document.create('my-element'); 

構(gòu)建自定義組件

當(dāng)前,這個(gè)自定義組件僅僅有框架,而沒(méi)有內(nèi)容,下面讓我們向其中添加一些內(nèi)容:

  1. //我們將提供'document.register'的第二個(gè)參數(shù): 
  2. document.register('my-element', { 
  3.   prototype: Object.create(HTMLElement.prototype, { 
  4.     createdCallback: { 
  5.       value: function() { 
  6.         this.innerHTML = '<h1>ELEMENT CREATED!</h1>'
  7.       } 
  8.     } 
  9.   }) 
  10. }); 

在這個(gè)例子中,我們?cè)O(shè)置自定義組件的prototype,使用Object.create 方法創(chuàng)建一個(gè)繼承于HTMLElement的對(duì)象。在這個(gè)方法中修改該組件的屬性 innerHTML。

我們定義了createdCallback方法,在每次聲明實(shí)例時(shí)調(diào)用。你同樣可以有選擇性的定義attributeChangedCallback、 enteredViewCallback 和leftViewCallback等方法。

目前為止我們實(shí)現(xiàn)了動(dòng)態(tài)修改自定義組件內(nèi)容的功能,我們?nèi)匀恍枰峁┳远x組件的封裝方法,用于隱藏其內(nèi)部組件。

#p#

使用Shadow DOM實(shí)現(xiàn)封裝

我們需要完善下createdCallback方法。本次,除了修改innerHTML之外,我們添加一些額外的操作:

  1. createdCallback: { 
  2.  
  3. value: function() { 
  4.  
  5. var shadow = this.createShadowRoot(); 
  6.  
  7. shadow.innerHTML = '<h1>SHADOW DOM!</h1>'
  8.  
  9.  

在這個(gè)例子中, 你會(huì)注意到‘SHADOW DOM!’,但是查看源碼時(shí)你會(huì)發(fā)現(xiàn)只有空白的<my-element /> 標(biāo)簽而已。這里使用創(chuàng)建Shadow Root 方法替代了直接修改頁(yè)面。

Shadow Root中的任何組件,是肉眼可見(jiàn)的,但是和當(dāng)前頁(yè)面的樣式和DOM API相隔離。這樣就實(shí)現(xiàn)了自定義組件是一個(gè)獨(dú)立組件的假象。

添加“輕量級(jí)DOM”

目前為止,我們的自定義組件是空標(biāo)簽,但是如果向其中添加內(nèi)部組件會(huì)出現(xiàn)什么現(xiàn)象呢?

我們假設(shè)自定義組件包含的節(jié)點(diǎn)如下,

  1. <my-element> 
  2.  
  3. 這是一個(gè)輕量級(jí) DOM。 
  4.  
  5. <i>hello</i> 
  6.  
  7. <i>world</i> 
  8.  
  9. </my-element> 

一旦針對(duì)于這個(gè)組件的 Shadow Root 被創(chuàng)建,它的子節(jié)點(diǎn)不再存在。我們這些隱藏的子節(jié)點(diǎn)封裝為輕量級(jí)DOM節(jié)點(diǎn)。

如果禁用了 Shadow DOM,上面這個(gè)例子僅僅會(huì)顯示為:這是一個(gè)輕量級(jí) DOM‘hello world’。

當(dāng)我們?cè)赾reatedCallback方法中設(shè)置 Shadow DOM后,我們可以使用新增內(nèi)容分配輕量級(jí)DOM組件到Shadow DOM 中。

  1. createdCallback: { 
  2.  
  3. value: function() { 
  4.  
  5. var shadow = this.createShadowRoot(); 
  6.  
  7. // 子組件'i' 標(biāo)簽現(xiàn)在已經(jīng)消失了 
  8.  
  9. shadow.innerHTML = 
  10.  
  11. ‘輕量級(jí) DOM 中的 "i" 標(biāo)簽為: ' + 
  12.  
  13. '<content select="i" />'
  14.  
  15. //現(xiàn)在,在 Shadow DOM 中只有 'i' 標(biāo)簽是可以見(jiàn)的。 
  16.  
  17.  

封裝樣式

Shadow DOM 最重要的作用是創(chuàng)建了和當(dāng)前頁(yè)面隔離的Web組件,使Web組件不受當(dāng)前頁(yè)面樣式和JaveScript腳本的影響。

  1. createdCallback: { 
  2.  
  3. value: function() { 
  4.  
  5. var shadow = this.createShadowRoot(); 
  6.  
  7. shadow.innerHTML = 
  8.  
  9. "<style>span { color: green }</style>" + 
  10.  
  11. "<span>I'm green</span>"
  12.  
  13.  

反之,在 Shadow DOM 中定義的樣式也不會(huì)影響之外的標(biāo)簽樣式。

  1. <my-element /> 
  2.  
  3. <span>I'm not green</span> 

#p#

揭露鉤子的秘密

當(dāng)隱藏自定義組件內(nèi)部標(biāo)記,有時(shí)也需要在當(dāng)前頁(yè)面對(duì)組件中的內(nèi)部特定組件進(jìn)行樣式設(shè)置。

例如,如果我們自定義一個(gè)日歷插件,在不允許用戶(hù)控制整個(gè)插件的情況下,允許最終用戶(hù)去定義按鈕的樣式。

這是其中的部分特性和偽組件:

  1. createdCallback: { 
  2.  
  3. value: function() { 
  4.  
  5. var shadow = this.createShadowRoot(); 
  6.  
  7. shadow.innerHTML = 'Hello <em part="world">World</em>'
  8.  
  9.  

這是在當(dāng)前頁(yè)面設(shè)置自定義組件內(nèi)部組件樣式的方法:

  1. my-element::part(world) { 
  2.  
  3. color: green; 
  4.  

這部分內(nèi)容介紹了封裝web組件的基本方式。Shadow DOM 是我們可以任意修改Web組件中的標(biāo)簽。在例子中,我們?cè)O(shè)置了“World”的樣式,但是使用者卻無(wú)法判斷它是<em>標(biāo)簽。

在你嘗試自定義Web組件之前,需要確保瀏覽器的相關(guān)特性已經(jīng)打開(kāi)。如果使用 Chrome,在 Chrome 中打開(kāi)chrome://flags ,并且開(kāi)啟“experimental Web Platform features”。

clip_image003[1]

這僅僅是個(gè)開(kāi)始

所有本文中介紹的內(nèi)容,都是模擬一些簡(jiǎn)單的瀏覽器標(biāo)準(zhǔn)行為。我們已經(jīng)習(xí)慣于和原生的瀏覽器組件進(jìn)行交互,因此自定義組件的步驟并不是想象中的那個(gè)難。Web組件最終提供我們一種實(shí)現(xiàn)簡(jiǎn)單、一致、可復(fù)用、封裝和組合部件的方法,這是一個(gè)有意義的開(kāi)始。

責(zé)任編輯:徐川 來(lái)源: cnblogs
相關(guān)推薦

2009-07-08 15:12:48

Java Servle

2010-08-03 13:06:15

Flex Builde

2013-08-29 14:12:52

Storm分布式實(shí)時(shí)計(jì)算

2024-02-26 09:13:35

WebComponents開(kāi)源項(xiàng)目

2010-07-20 16:19:54

Perl

2018-03-22 14:59:13

Docker入門(mén)容器

2011-09-02 10:59:10

jQuery Mobi

2013-06-24 13:38:34

HTML5 DataList

2010-06-18 16:56:50

UML建模語(yǔ)言

2010-05-21 12:50:45

Subversion快

2010-07-27 15:53:15

2011-07-21 10:29:18

iPhone 開(kāi)發(fā)

2010-08-03 14:37:30

Flex入門(mén)教程

2010-06-13 09:45:35

Widget開(kāi)發(fā)

2013-08-29 14:28:09

StormHadoop

2012-05-10 08:29:46

XcodeiOSPhoneGap

2024-11-12 15:46:37

2022-06-16 07:31:41

Web組件封裝HTML 標(biāo)簽

2010-03-12 14:04:32

Python入門(mén)教程

2010-05-27 17:27:45

Subversion快
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)