成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

什么是Shadow Dom?

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

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

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

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

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

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

我的名字是DOM,Shadow DOM

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

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

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

slider

很簡單吧,這里有一個滑槽,還有一個滑塊可以沿滑槽滑動。

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

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

這是一種魔法么?

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

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

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

slider

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

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

  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.     // 注意:這里只是模擬,不是真實的API 
  11.     foo.shadow = document.createElement('p'); 
  12.     foo.shadow.textContent = 'I gotta wear shades'
  13. </script> 
  14. </body> 
  15. </html> 

我們獲得了一個這樣的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

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

事件的情況

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

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

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

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

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

通過CSS訪問(Reaching into)Shadow

另一個需要提到的技巧是怎樣通過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子樹。但事實上,這里有一些很方便的偽元素,可以取到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

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

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

講完了這些令人驚嘆的能力,我們想象一樣,如果給一個有shadown DOM子樹的元素插入子元素會怎樣?我們來實驗一下:

  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)的一部分,可以被遍歷到,但是不會渲染!它是不是很有用呢?不一定,但是如果你需要的話它確實就在那等你。

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

  1. // 注意:這里只是模擬,不是真實的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,你會看到這個:

  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)你添加子元素的時候,從DOM樹中看像一個正常的子元素,但是渲染的時候,他們從“洞(hole)”中進到了shadow DOM子樹。

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

瀏覽器中什么時候才會有呢?

家庭作業(yè)

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

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

如果你不是一個框架作者,你仍然可以參與進來,你可以給shadown DOM加油,也可以將這份快樂傳播到你最喜歡的社交網(wǎng)絡(luò)上,因為快樂就是我們工作的全部。

附:SVG和shadow DOM

差點忘了,至于你信不信,我反正信了,SVG確實已經(jīng)用到了shadow DOM,從一開始就是這樣。但是比較麻煩的是,SVG的shadow DOM非常……非常……水(shady),不不,不是這個詞,是另一個詞,以sh開頭,以y結(jié)尾。(注:對英文語境不是太熟悉,評論中有人提到是 shy。)對對,就是它!我可以繼續(xù)說,但是請相信我對SVG shadow DOM的評價?;蛘吣憧梢圆榭次臋n。

原文地址: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場景

2010-09-28 11:32:30

HTML DOM是什么

2021-03-20 22:46:22

IaaSSaaSPaaS

2023-09-01 13:49:00

內(nèi)存進程線程

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操作

2020-11-20 10:51:03

云計算

2010-09-28 11:11:23

XML DOMHTML DOM

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

二進制編程語言

2016-06-13 14:49:40

2012-04-25 17:15:44

EA
點贊
收藏

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

主站蜘蛛池模板: 亚洲欧洲在线观看视频 | 久久亚| 亚州无限乱码 | 欧美一级免费看 | 成人欧美一区二区三区黑人孕妇 | 中文字幕国 | 一区二区三区欧美 | 超碰在线人人干 | 国产精品一区久久久 | 国产一区91在线 | 精品久久久久久久久久久久久久 | 成人av免费 | 黄色大片免费观看 | 久久久久国产一区二区 | 精品中文字幕视频 | 欧美精品福利视频 | 国产精品91久久久久久 | 免费高清av| 免费电影av| 男女黄网站 | 欧美日韩一区二区三区四区五区 | 久久国产欧美日韩精品 | 999久久久| 国产精品一区二区在线免费观看 | 亚洲精品一区av在线播放 | 亚洲欧洲视频 | 丁香婷婷久久久综合精品国产 | 九色av| 在线观看成人av | 久久久久久成人 | 日韩一二三区 | 亚洲精品成人网 | 国产一级视频免费播放 | 麻豆av在线免费观看 | 亚洲精品欧美 | 可以看黄的视频 | 午夜精品一区二区三区在线观看 | 亚洲福利在线视频 | 北条麻妃av一区二区三区 | 亚洲精品久久久久久一区二区 | 国产精品日韩欧美一区二区三区 |