Shadow DOM獲取Shadow host的內容

Shadow DOM(二)中,介紹了與Shadow DOM相關的概念,包括Shadow host等等。

本文將重點介紹如何將Light DOM中的內容傳到Shadow DOM中。

而在Shadow DOM 與HTML Templates一文的示例中可以看到Shadow host: <div class="host">Hello World!</div>的內容在該節點創建並附加Shadow Root後並沒有在瀏覽器中得到渲染,也就是說Shadow host的內容,這裏爲“Hello World!"沒能在瀏覽器中渲染出來,取而代之的是Shadow DOM中的內容得到了渲染,及該例中的template中的內容得到了渲染,然後在瀏覽器中運行後,只看到了Shadow DOM中的內容。

然後,在實際應用中,這種完全用Shadow DOM替換Light DOM中內容的方式並不是很有用,我們期望實現的可以通過從Shadow host中獲取內容,然後使用Shadow DOM提供的結構來展現。類似這樣的內容與展現分離,可以讓我們在處理頁面如何渲染的過程中更加靈活。

爲了能夠使用我們在Shadow host的內容,我們需要引入一個新的標籤,那就是<content>標籤。

首先通過一個示例來了解:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo</title>
</head>
<body>
    <div class="host">Hello Wrold!</div>
    <template>
        <h2>Hi, my name is winstar, and I can say: <content></content></h2>
    </template>
    <script>
        var host = document.querySelector('.host');
        var root = host.createShadowRoot();
        var tmpl = document.querySelector('template');
        root.appendChild(document.importNode(tmpl.content, true));
    </script>
</body>
</html>

在Chrome瀏覽器中運行,效果如圖:


可以看到,在源代碼中的template,包含了<content>標籤,而在運行結果中,也可以看到Shadow host中的內容“Hello World!"也被渲染了出來,而且就是<content>標籤所在的位置。

通過<content>標籤,我們在模板中創建了一個插入點,這個插入點可以投射來自Shadow host中的內容,如本例中的“Hello World!”投射到<content>所在位置,並出現在我們的h2標籤中。

插入點的功能非常強大,它允許我們在不手動修改源代碼(這裏的源代碼指的是Shadow host中出現的內容)的基礎上也可以改變渲染的順序,也讓開發者可以有選擇性地選取哪些內容應該得到渲染。

剛剛說到,插入點可以改變渲染的順序,有選擇性地選取哪些內容應該得到渲染,這個是如何實現的呢?爲了實現這一目的,必須讓<content>具備選擇能力,讓它知道選擇哪裏的內容插入到指定的位置。爲了做到這一點,規範賦予了<content>標籤具有select屬性。這個select屬性使用CSS選擇器來匹配選擇需要渲染的內容。

例如,<content select=".user-name">將在Shadow host中查找任何具有class爲user-name的匹配元素,並將所有匹配元素插入到該<content>標籤中以被渲染。

改變順序示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo</title>
</head>
<body>
    <div class="host">
        <div class="name">winstar</div>
        <div class="age">28</div>
    </div>
    <template>
        <h2><content select=".name"></content></h2>
        <h2><content select=".age"></content></h2>
    </template>
    <script>
        var host = document.querySelector('.host');
        var root = host.createShadowRoot();
        var tmpl = document.querySelector('template');
        root.appendChild(document.importNode(tmpl.content, true));
    </script>
</body>
</html>

運行結果:


在該示例中,可以看到<content>通過select屬性分別選取了Shadow host中對應的內容,並且得以被渲染出來。下面我們在不需改內容結構的情況下,調整渲染的順序。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo</title>
</head>
<body>
    <div class="host">
        <div class="name">winstar</div>
        <div class="age">28</div>
    </div>
    <template>
        <h2><content select=".age"></content></h2>
        <h2><content select=".name"></content></h2>
    </template>
    <script>
        var host = document.querySelector('.host');
        var root = host.createShadowRoot();
        var tmpl = document.querySelector('template');
        root.appendChild(document.importNode(tmpl.content, true));
    </script>
</body>
</html>

運行結果:



可以看到,瀏覽器渲染內容的順序跟前面確實改變了,但通過【審查元素】可以發現Shadow host的內容(紅框中的內容)屬性卻保持跟原來一模一樣。

因此,可以說內容是在Shadow host中的,而決定渲染的是Shadow root/Shadow DOM。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章