Shadow DOM的简单实现

2017年07月15日Web前端

紧接Shadow DOM的简介,介绍关于Shadow DOM的使用方法。

一、例子

<div>
    <p>
        <span>hello</span>
        <span id="box">world</span>
    </p>
</div>

像这段HTML,在浏览器中被解析成DOM时,每一个元素就是一个节点,整体构成了一个节点树。

而Shadow DOM可以让我们自己创建节点树,依旧是以上的HTML代码,加上以下的JS代码:

var oBox = document.querySelector('#box');
// 创建 shadow DOM
var shadowRoot = oBox.createShadowRoot();
shadowRoot.innerHTML = 'JavaScript';

首先我们选取了一个id是box的元素作为宿主对象(shadow host),然后使用createShadowRoot()方法给宿主对象增加了一个shadow root的新节点,影子根节点作为影子树的第一个节点,其他的节点都是它的子节点。在控制台下得到以下结构:

当然在页面上发现,world并没有渲染出来,显示的是JavaScript。也就是说宿主对象并没有被渲染,取而代之的是内部的元素。

加入我们想加入其他更多的元素的话,为何不使用原生的创建元素的方式试下呢?

var oBox = document.querySelector('#box');
var shadowRoot = oBox.createShadowRoot();
shadowRoot.textContent = 'JavaScript';

var html = document.createElement('span');
html.textContent = ',HTML';
var css = document.createElement('span');
css.textContent = ',CSS';

shadowRoot.appendChild(html);
shadowRoot.appendChild(css);

// 或者直接
//shadowRoot.innerHTML = 'JavaScript<span>,HTML</span><span>,CSS</span>';

我们使用了原生的createElement()方法创建了元素并添加到影子DOM下,使用了textContent给元素赋值了内容(textContent用法不说啦)。当然,也可用innerHTML一步到位。此时,HTML的结构是这样的,

我们发现Shadow DOM和普通的DOM似乎没有太大的区别,操作普通DOM的方式在这都可以使用。当然,宿主元素还是没有被渲染出来。

二、content 标签

在前面的例子中,我们使用操作普通DOM的API给影子DOM添加了一些DOM元素,并且他们也能成功的在页面上显示出来。

<div id="box">world</div>

<template class="box-template">
    hello,<content></content>
</template>

<script type="text/javascript">
var oBox = document.querySelector('#box');

var shadowRoot = oBox.createShadowRoot();
var template = document.querySelector('.box-template');

shadowRoot.appendChild(document.importNode(template.content, true));
</script>

在这,我们使用一个模板标签