淺談 shadow dom 中的 template 和 slot

最近一個內部系統(tǒng)可視化設計器的布局在用戶升級 chrome 到 53 版本之后,里面的坑位增加按鈕消失了畔乙,經過排查發(fā)現(xiàn)君仆,坑位的標簽使用了slot,而坑位中的按鈕是通過 css 的 empty 偽類實現(xiàn)的牲距,即坑位為空時返咱,出現(xiàn)增加按鈕,但現(xiàn)在為什么突然無效了呢牍鞠?

slot的名字換成其他標簽名咖摹,發(fā)現(xiàn)樣式頓時生效,于是猜測是slot作為特殊標簽被 chrome 設置了特定的行為难述,經過查閱資料發(fā)現(xiàn)slotshadow dom 中的內置標簽萤晴。

現(xiàn)在我們來了解下 shadow dom 以及與其相關的兩個特殊標簽 templateslot

何為shadow dom

shadow dom胁后,顧名思義店读,影子節(jié)點,它是 web components 規(guī)范的一個子集攀芯,主要為了解決dom對象的封裝屯断,通常的dom,其js行為和css樣式極易受到別的代碼的干擾侣诺,但shadow dom規(guī)定了只有其宿主才可定義其表現(xiàn)殖演,外部的api是無法獲取到shadow dom中的東西。

由于shadow dom是影子元素紧武,因此其必須捆綁一個宿主元素剃氧,宿主元素事實上成為了“傀儡”,宿主元素的內容將被隱藏阻星,而shadow dom的內容將展示出來朋鞍,以下是一個例子:

html:
<div id="con">
    沒什么卵用的文字
</div>

js:
var host = document.querySelector('#con');
var root = host.attachShadow({mode:'open'});//為宿主附加一個影子元素

root.innerHTML = "我來自shadow dom";//為影響元素附上內容,shadow dom的api和普通dom的大致相同

最終效果:

我來自shadow dom

可以看到妥箕,宿主的內容確實被掩蓋了滥酥,然而通過chrome的devtools,可以看到宿主的原內容以及背后的shadow dom:

shadow dom中的template

前面說了畦幢,shadow dom可以實現(xiàn)dom的隔離坎吻,比如樣式的封裝,那么如何實現(xiàn)呢宇葱?shadow規(guī)定了一種名為template的標簽瘦真,這種標簽類似我們經常用的<script type='tpl'>刊头,它不會被解析為dom樹的一部分,template的內容可以被塞入到shadow dom中并且反復利用诸尽,在template中可以設置style原杂,但只對這個template中的元素有效,看下示例:

html:
<style>
span {
  background-color:blue;/*設置頁面所有span背景為藍色您机,然而對shadow dom沒什么卵用*/
}
</style>
<div id="con">
    沒什么卵用的文字
  </div>
   <template id="tpl">
     <style>
       span {
         color:red;
       }
     </style>
     <span>hello world</span>
   </template>

js:
var host = document.querySelector('#con');
var root = host.attachShadow({mode:'open'});

var con = document.getElementById("tpl").content.cloneNode(true);

root.appendChild(con);

效果截圖:

<span style='color:red'>hello world</span>

可以看到穿肄,template的內容被塞入到宿主,并且其文案被設置為紅色际看,而body 中對 span 設置為藍色背景卻沒有生效咸产;另外這里要注意document.getElementById("tpl").content中的content屬性,它是template標簽的特有屬性仲闽,你可以通過嗅探該屬性來判斷瀏覽器是否支持shadow dom和template標簽脑溢。

shadow dom的slot標簽

由于shadow dom的內容會掩蓋宿主的內容,那么現(xiàn)在問題來了蔼囊,我就是想把宿主的內容顯示出來怎么辦焚志?

最新的shadow dom草案支持了一個叫slot標簽的東西,slot是一個插槽畏鼓,一個坑位酱酬,可以在template中定義坑位,然后宿主中的內容可以標記屬于哪一個坑位云矫,這樣一個蘿卜一個坑膳沽,宿主的內容就會被正確地插入到template所標記的位置去,還是來看一個例子:

html:
<div id="con">
    沒什么卵用的文字
    <span slot="main1">
      坑位1
    </span>
    <span slot="main2">
      坑位2
    </span>
    沒什么卵用的文字 </div>
  <template id="tpl">tpl begin
    <slot name="main1">
    </slot>
    <slot name="main2">
    </slot>
    tpl end
      </template>

js:
var host = document.querySelector('#con');
var root = host.attachShadow({mode:'open'});

var con = document.getElementById("tpl").content.cloneNode(true);

root.appendChild(con);

最終的效果是:

tpl begin 坑位1 坑位2 tpl end

可以看到让禀,宿主中的兩個span分別插入到了其標記的slot坑位中挑社。在slot出現(xiàn)之前,仍然可以實現(xiàn)類似的功能巡揍,只不過標簽名叫content痛阻。

結語

現(xiàn)在我們來解釋一下文章開頭出現(xiàn)的問題的原因,由于 slot標簽僅僅是一個占位符而已腮敌,其最終會被宿主標記了該位置的內容替換(注意是替換阱当,而不是插入),因此沒必要對slot標簽設置樣式糜工,這就是為啥chrome 53忽略其樣式的原因弊添,無獨有偶,最新版的ios 10默認瀏覽器也會隱藏slot捌木,因為slot中并不需要顯示任何東西油坝。

借鑒vue的思想,我們在編譯階段把slot編譯成div,從而解決了這個問題澈圈,順便提醒一下彬檀,shadow dom是非常新的技術,目前還處在試驗階段瞬女,而且標準還不確定凤覆,請不要在生產環(huán)境使用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末拆魏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子慈俯,更是在濱河造成了極大的恐慌渤刃,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贴膘,死亡現(xiàn)場離奇詭異卖子,居然都是意外死亡,警方通過查閱死者的電腦和手機刑峡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門洋闽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人突梦,你說我怎么就攤上這事诫舅。” “怎么了宫患?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵刊懈,是天一觀的道長。 經常有香客問我娃闲,道長虚汛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任皇帮,我火速辦了婚禮卷哩,結果婚禮上,老公的妹妹穿的比我還像新娘属拾。我一直安慰自己将谊,他們只是感情好,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布捌年。 她就那樣靜靜地躺著瓢娜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪礼预。 梳的紋絲不亂的頭發(fā)上眠砾,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天,我揣著相機與錄音,去河邊找鬼褒颈。 笑死柒巫,一個胖子當著我的面吹牛,可吹牛的內容都是我干的谷丸。 我是一名探鬼主播堡掏,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼刨疼!你這毒婦竟也來了泉唁?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤揩慕,失蹤者是張志新(化名)和其女友劉穎亭畜,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迎卤,經...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡拴鸵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜗搔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劲藐。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖樟凄,靈堂內的尸體忽然破棺而出聘芜,到底是詐尸還是另有隱情,我是刑警寧澤不同,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布厉膀,位于F島的核電站,受9級特大地震影響二拐,放射性物質發(fā)生泄漏服鹅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一百新、第九天 我趴在偏房一處隱蔽的房頂上張望企软。 院中可真熱鬧,春花似錦饭望、人聲如沸仗哨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厌漂。三九已至,卻和暖如春斟珊,著一層夾襖步出監(jiān)牢的瞬間苇倡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留旨椒,地道東北人晓褪。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像综慎,于是被迫代替她去往敵國和親涣仿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內容