偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

什么是Shadow Dom?

移動(dòng)開發(fā)
如果我需要把每個(gè)自定義的按鈕都放到iframe里,你是什么感覺,會(huì)不會(huì)瘋掉?所以,我們需要一些更好的東西。事實(shí)上,大部分的瀏覽器已經(jīng)變相地提供了一種強(qiáng)大技術(shù)去隱藏一些實(shí)現(xiàn)細(xì)節(jié)。這個(gè)技術(shù)就是所謂的“shadow DOM”。

如果你做過網(wǎng)站,那么很可能你已經(jīng)用過一些JavaScript類庫。既然如此,你可能會(huì)對(duì)這些不知名的類庫作者心存感激。

這些作者——web開發(fā)領(lǐng)域的勇士們——都面對(duì)著同樣的一個(gè)問題——封裝。他們會(huì)花大量的精力在面向?qū)ο蟮慕?jīng)典問題之一上面,即如何封裝自己的代碼,以便與類庫使用者的代碼分離。

除了SVG,現(xiàn)在的Web平臺(tái)只提供了一種原生的方法去隔離代碼塊,這并不優(yōu)雅。沒錯(cuò),我說的就是iframe。對(duì)大部分需要封裝的場(chǎng)景來說,frames太重而且限制太多。

如果我需要把每個(gè)自定義的按鈕都放到iframe里,你是什么感覺,會(huì)不會(huì)瘋掉?

所以,我們需要一些更好的東西。事實(shí)上,大部分的瀏覽器已經(jīng)變相地提供了一種強(qiáng)大技術(shù)去隱藏一些實(shí)現(xiàn)細(xì)節(jié)。這個(gè)技術(shù)就是所謂的“shadow DOM”。

我的名字是DOM,Shadow DOM

Shadow DOM是指瀏覽器的一種能力,它允許在文檔(document)渲染時(shí)插入一棵DOM元素子樹,但是這棵子樹不在主DOM樹中。看一個(gè)簡(jiǎn)單的slider:

  1. <input id="foo" type="range"/> 

把這段代碼放到webkit內(nèi)核的瀏覽器中,它會(huì)這樣顯示:

slider

很簡(jiǎn)單吧,這里有一個(gè)滑槽,還有一個(gè)滑塊可以沿滑槽滑動(dòng)。

嗯。一切看起來都那么美好,喝杯咖啡先……等下等下,這里居然有一個(gè)可以在input元素中滑動(dòng)的元素!為什么我不能通過JavaScript看到它?

  1. var slider = document.getElementsById("foo"); 
  2. console.log(slider.firstChild); // 返回 null 

這是一種魔法么?

我的觀點(diǎn)來看,不是。這只是shadow DOM在起作用。你看,瀏覽器的開發(fā)者們已經(jīng)意識(shí)到了手工編寫這些DOM元素的表現(xiàn)和行為很困難而且很SB。所以,從一定程度上講,他們騙了我們,給了我們一個(gè)輸入框,但擁有比輸入框更多的功能。

他們?yōu)槟?mdash;—web開發(fā)者設(shè)定了一個(gè)邊界,界定了哪些是你可以訪問的,哪些實(shí)現(xiàn)細(xì)節(jié)是訪問不到的。然而,瀏覽器本身卻可以隨意跨越這個(gè)邊界。設(shè)置這 樣一個(gè)邊界之后,它們就可以在你看不見的地方使用熟悉的web技術(shù)、同樣的HTML元素去創(chuàng)建更多的功能,而不是像你一樣要在頁面上用div和span來 堆。

有一些很簡(jiǎn)單,就像上面說的slider。而有一些卻相當(dāng)復(fù)雜。我們來看一下video元素,它有一些按鈕、進(jìn)度條、hover態(tài)的音量控制,像這樣:

slider

所有的這一切都只是HTML和CSS——但是是隱藏在shadow DOM子樹中的。

借用XXX的一首詩,“它是怎樣工作的?”為了直觀一些,我們假裝可以用JavaScript操作它。看這個(gè)簡(jiǎn)單的頁面:

  1. <html> 
  2. <head> 
  3. <style> p { color: Green; } </style> 
  4. </head> 
  5. <body> 
  6. <p>My Future is so bright</p> 
  7. <div id="foo"></div> 
  8. <script> 
  9.     var foo = document.getElementById('foo'); 
  10.     // 注意:這里只是模擬,不是真實(shí)的API 
  11.     foo.shadow = document.createElement('p'); 
  12.     foo.shadow.textContent = 'I gotta wear shades'
  13. </script> 
  14. </body> 
  15. </html> 

我們獲得了一個(gè)這樣的DOM樹:

  1. <p>My Future is so bright</p> 
  2. <div id="foo"></div> 

但是它像是被這樣渲染出來的:

  1. <p>My Future is so bright</p> 
  2. <div id="foo"> <!-- shadow subtree begins --> 
  3.     <p>I gotta wear shades</p> 
  4. </div> <!-- shadow subtree ends --> 

看起來是這樣:

slider

注意一下,為什么渲染的句子的第二部分不是綠色的?這是因?yàn)槲臋n(document)中選擇器p不能獲取到shadown DOM。很酷對(duì)不對(duì)?!如果一個(gè)框架開發(fā)者被賦予這樣的能力會(huì)怎么樣?想象一下你只需要寫你的widget,而不用擔(dān)心被不知哪里蹦出來的選擇器愚弄…… 簡(jiǎn)直令人陶醉。

事件的情況

為了保持自然,shadow DOM子樹中的事件可以在文檔(document)中被監(jiān)聽。比如,你點(diǎn)擊一下audio元素中的靜音按鈕,你可以在一個(gè)包裹它的div中監(jiān)聽到這個(gè)事件。

  1. <div onclick="alert('who dat?')"> 
  2.     <audio controls src="test.wav"></audio> 
  3. </div> 

但是,如果你要確認(rèn)事件的來源,會(huì)發(fā)現(xiàn)它是audio元素,而不是它內(nèi)部的按鈕。

  1. <div onclick="alert('fired by:' + event.target)"> 
  2.     <audio controls src="test.wav"></audio> 
  3. </div> 

為什么這樣?因?yàn)楫?dāng)事件穿過shadown DOM邊界的時(shí)候,會(huì)被重新設(shè)定target,以避免暴露shadow DOM子樹內(nèi)部結(jié)構(gòu)。用這種方式,你可以監(jiān)聽到從shadow DOM中產(chǎn)生的事件,而實(shí)現(xiàn)者也可以繼續(xù)隱藏細(xì)節(jié)。

通過CSS訪問(Reaching into)Shadow

另一個(gè)需要提到的技巧是怎樣通過CSS來訪問shadow DOM子樹。假設(shè)我想自定義我的slider。我想讓它有一些樣式,而不是系統(tǒng)原生的那樣,像這樣:

  1. input[type=range].custom {  
  2.     -webkit-appearance: none;  
  3.     background-color: Red;  
  4.     width200px;  
  5. }  

結(jié)果如下:

slider

很好,但是我怎樣定義滑塊的樣式呢?我們已經(jīng)知道,常規(guī)的CSS選擇器并不能獲取到shadow DOM子樹。但事實(shí)上,這里有一些很方便的偽元素,可以取到shadow DOM子樹中的元素。例如,slider中的滑塊在webkit中可以這樣訪問:

  1. input[type=range].custom::-webkit-slider-thumb { 
  2.     -webkit-appearance: none
  3.     background-color: Green; 
  4.     opacity: 0.5
  5.     width10px
  6.     height40px

樣子如下:

slider

很***對(duì)不對(duì)?想想看,你可以為shadow DOM子樹中的元素賦予樣式,而不需要真的訪問到這些元素。而這些shadow DOM的作者有了決定哪些部分可以被賦予樣式的權(quán)利。如果你是作者,在做一些UI widget toolkit的時(shí)候,難道不想有這樣的能力嗎?

帶有洞(hole)的Shadow DOM,無窮的想象力

講完了這些令人驚嘆的能力,我們想象一樣,如果給一個(gè)有shadown DOM子樹的元素插入子元素會(huì)怎樣?我們來實(shí)驗(yàn)一下:

  1. // Create an element with a shadow DOM subtree. 
  2. var input = document.body.appendChild(document.createElement('input')); 
  3. // Add a child to it. 
  4. var test = input.appendChild(document.createElement('p')); 
  5. // .. with some text. 
  6. test.textContent = 'Team Edward'

結(jié)果如下:

slider

哇!歡迎來到twilight DOM的世界!它是文檔(document)的一部分,可以被遍歷到,但是不會(huì)渲染!它是不是很有用呢?不一定,但是如果你需要的話它確實(shí)就在那等你。

但是,如果我們真的有能力把元素的子元素放入shadow DOM子樹中會(huì)怎么樣?想象一下shadow DOM是一個(gè)模板,通過它的某個(gè)洞(hole)可以看到內(nèi)部的子元素:

  1. // 注意:這里只是模擬,不是真實(shí)的API 
  2. var element = document.getElementById('element'); 
  3. // 創(chuàng)建shadow DOM子樹 
  4. element.shadow = document.createElement('div'); 
  5. element.shadow.innerHTML = '<h1>Think of the Children</h1>' + 
  6.     '<div class="children">{{children-go-here}}</div>'
  7. // Now add some children. 
  8. var test = element.appendChild(document.createElement('p')); 
  9. test.textContent = 'I see the light!'

如果你去遍歷DOM,你會(huì)看到這個(gè):

  1. <div id="element"> 
  2.     <p>I see the light</p> 
  3. </div> 

但是像是這樣渲染出來的:

  1. <div id="element"> 
  2.     <div> <!-- shadow tree begins --> 
  3.         <h1>Think of the Children</h1> 
  4.         <div class="children"> <!-- shadow tree hole begins --> 
  5.             <p>I see the light</p> 
  6.         </div> <!-- shadow tree hole ends --> 
  7.     </div> <!-- shadow tree ends -->  
  8. </div> 

當(dāng)你添加子元素的時(shí)候,從DOM樹中看像一個(gè)正常的子元素,但是渲染的時(shí)候,他們從“洞(hole)”中進(jìn)到了shadow DOM子樹。

寫到這里,你應(yīng)該會(huì)承認(rèn),這真的很酷,也會(huì)問:

瀏覽器中什么時(shí)候才會(huì)有呢?

家庭作業(yè)

你認(rèn)為聽完了這么多說教的內(nèi)容會(huì)沒有家庭作業(yè)?作為一個(gè)JavaScript類庫或者框架的開發(fā)者,嘗試者去想象一下你可以利用shadow DOM制作的跟之前不一樣的偉大的東西。然后想一下shadow DOM可以應(yīng)用到的一些特定的使用場(chǎng)景(加上真實(shí)的或者模擬的代碼)。

***,共享你想到的使用場(chǎng)景到public-webapps郵件列表。關(guān)于在web平臺(tái)中加入這種能力的討論正在進(jìn)行,我們需要你的幫助。

如果你不是一個(gè)框架作者,你仍然可以參與進(jìn)來,你可以給shadown DOM加油,也可以將這份快樂傳播到你最喜歡的社交網(wǎng)絡(luò)上,因?yàn)榭鞓肪褪俏覀児ぷ鞯娜俊?/p>

附:SVG和shadow DOM

差點(diǎn)忘了,至于你信不信,我反正信了,SVG確實(shí)已經(jīng)用到了shadow DOM,從一開始就是這樣。但是比較麻煩的是,SVG的shadow DOM非常……非常……水(shady),不不,不是這個(gè)詞,是另一個(gè)詞,以sh開頭,以y結(jié)尾。(注:對(duì)英文語境不是太熟悉,評(píng)論中有人提到是 shy。)對(duì)對(duì),就是它!我可以繼續(xù)說,但是請(qǐng)相信我對(duì)SVG shadow DOM的評(píng)價(jià)。或者你可以查看文檔。

原文地址:http://www.toobug.net/article/what_is_shadow_dom.html

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

2014-05-26 16:29:12

Shadow DomWeb Compone

2022-02-10 22:24:05

DOM結(jié)構(gòu)工具

2020-09-28 14:26:42

Shadow DOMWeb組件

2022-07-01 07:31:18

AhooksDOM場(chǎng)景

2010-09-28 11:32:30

HTML DOM是什么

2021-03-20 22:46:22

IaaSSaaSPaaS

2023-09-01 13:49:00

內(nèi)存進(jìn)程線程

2020-07-14 14:59:00

控制反轉(zhuǎn)依賴注入容器

2017-12-19 21:29:58

物聯(lián)網(wǎng)區(qū)塊鏈大數(shù)據(jù)

2010-03-09 11:09:05

Linux etcshadow

2023-09-25 10:26:05

DOMCSS

2016-04-06 11:29:58

JavaScriptDOM操作

2010-09-28 11:11:23

XML DOMHTML DOM

2020-11-20 10:51:03

云計(jì)算

2018-01-30 11:17:56

集群分布式SOA?

2023-09-14 15:00:31

2009-07-16 09:56:32

什么是iBATIS

2022-08-15 06:00:00

二進(jìn)制編程語言

2016-06-13 14:49:40

2012-04-25 17:15:44

EA
點(diǎn)贊
收藏

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