iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 5
0
Modern Web

從零開始遲來的Web開發筆記系列 第 5

WebCompose超有用網頁模組化 - Shadow DOM

前置

今天來試一下Shadow DOM。
上次說到HTML imports的CSS和Javascript會影響到原本的DOM Tree。這次我要用Shadow DOM來隔離這個影響。Shadow DOM有點像是沙盒(SandBox),在裏面做的東西和外面分開。不過在開始嘗試之前,需要先把之前兩份HTML改成下面的樣子:

hello.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <title>for test</title>
    <link rel="import" href="./my-header.html">
  </head>
  <body>
    <div id="myheader"></div>
    <h1>Hello World For Test</h1>
  </body>
  <script>
    var my_header = document.querySelector("#myheader");
    var my_import = document.querySelector('link[rel="import"]').import
    my_import = my_import.querySelector("#mytemplate");
  </script>
</html>

my-header.html

<template id="mytemplate">
  <h1>This is Header</h1>

  <style>
    h1{
    color:red;
    }
  </style>

</template>

關於第一個hello.html,要注意的是第方有: div#myheader是之後要插入的位置,並在Script裡已經先把一些元素取得。可以先試試看my_header.innerHTML = my_import.innerHTML效果如何,應該會連同原本的文字一起變色。

然後my-header.html,裏面原本所有內容用<template></template>標籤包裝起來,並且給與ID比較好取得。
關於template,可以參考MDN說明。簡單說template的內容,包含HTML、CSS和Javascript都不會被執行。透過這點,就可以將內容真的只最爲內容,甚至不會被顯示出來(顯示出來表示HTML被執行了)。

使用Shadow DOM

過去貌似在Chrome可以用createShadowRoot建立Shadow DOM,不過這個方法已經被棄用,儘管Chrome好像還支援,但還是來使用新方法吧--attachShadow

    // 建立Shadow DOM
    var my_shadow = my_header.attachShadow({mode:"open"})
    
    // 將預計import的內容寫入Shadow DOM
    my_shadow.innerHTML = my_import.innerHTML

加入上面script以後,可以發現受到template裡的CSS影響的,也只有Shadow DOM裡的h1

attachShadow模式說明

mode給與的值可以是:"open"或是"closed"
按照說明是能不能取得外部(也就是hello.html)的內容,不過我試了一下好像沒什麼差別......可能是對Javascript有影響?


** 完整的hello.html **

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <title>for test</title>
    <link rel="import" href="./my-header.html">
  </head>
  <body>
    <div id="myheader"></div>
    <h1>Hello World For Test</h1>
  </body>
  <script>
    var my_header = document.querySelector("#myheader");
    var my_import = document.querySelector('link[rel="import"]').import
    my_import = my_import.querySelector("#mytemplate");

    var my_shadow = my_header.attachShadow({mode:"open"})
    my_shadow.innerHTML = my_import.innerHTML
  </script>
</html>

上一篇
WebCompose超有用網頁模組化 - 顯示HTML imports中的內容
下一篇
WebCompose超有用網頁模組化 - CustomElementRegistry
系列文
從零開始遲來的Web開發筆記30

尚未有邦友留言

立即登入留言