what's a Web Components(上)

394 阅读3分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

序言

最近在学插件化相关的东西,有了解到很多工程化相关的技术,今天我们要学习的就是其中之一,Web Components。 ​

学习一种知识,首先要明白这个知识是什么,解决了什么问题,为什么要学,今天我们学习的 Web Components ,翻译过来是:web 组件,但是 Web Components不是单一的规范,而是一系列的技术组成。 包括templateCustom ElementShadow DOMHTML Import四种技术规范。

template

标签表示网页中某些重复出现的部分的代码模板。它存在于DOM之中,但是在页面中不可见。 ​

特点

<template></template>标签包裹,里面包含很多插槽和变量,使页面元素可以支持复用。 通常解决重复 HTML 代码的复用问题。 ​

动手试试

下面的代码用来检查,浏览器是否支持 template 标签,可以复制到控制台体验一下。

function supportsTemplate() {
  return 'content' in document.createElement('template');
}
​
if (supportsTemplate()) {
     console.log('浏览器支持')
} else {
   console.log('浏览器不支持')
}

document.importNode()

别的页面的 template 模板,可以使document.importNode()。 ​

例如,想要获取一个iframe中的 node 节点。可以使用以下的方法获取,可能有人会想,为什么不直接把获取的元素节点添加进去,因为如果是其他页面的模板,必须通过document.importNode导入后才可使用,使用实例如下:

var iframe = document.getElementsByTagName("iframe")[0];
var oldNode = iframe.contentWindow.document.getElementById("myNode");
var newNode = document.importNode(oldNode, true);
document.getElementById("container").appendChild(newNode);

插入外部文档节点之前,必须用document.importNode方法先将这个节点准备好。 document.importNode方法接受两个参数,第一个参数是外部文档的DOM节点,第二个参数是一个布尔值,表示是否连同子节点一起克隆,默认为 false。大多数情况下,必须显式地将第二个参数设为true。

Shadow DOM

所谓Shadow DOM指的是,浏览器将模板、样式表、属性、JavaScript代码等,封装成一个独立的DOM元素,外部的设置无法影响到其内部,而内部的设置也不会影响到外部,与浏览器处理原生网页元素,就像<style>里的 scoped 一样。

Shadow DOM元素必须依存在一个现有的DOM元素之下,通过createShadowRoot方法创造,然后将其插入该元素。

通过使用 innerHTML 属性,可以为 Shadow DOM 。

var shadowRoot = element.createShadowRoot();
shadowRoot.innerHTML = '<p>Here is some new text</p>';
shadowRoot.innerHTML += '<style>p { color: red };</style>';
document.body.appendChild(shadowRoot);

我们再看一个案例来感受一下

<div id="nameTag">coolFish</div>

<template id="nameTagTemplate">
  <style>
    .outer {
      border: 2px solid brown;
    }
  </style>

  <div class="outer">
    <div class="boilerplate">
      Hi! My name is
    </div>
    <div class="name">
      coolFish
    </div>
  </div>
</template>

上面为一个div元素和一个模板,接下来我们把模板应用到div上。

var shadow = document.querySelector('#nameTag').createShadowRoot();
var template = document.querySelector('#nameTagTemplate');
shadow.appendChild(template.content.cloneNode(true));

我们使用 createShadowRoot 创建的 Shadow DOM的根元素,然后在此节点进行构造的元素,就是 Shadow DOM,拥有样式方法隔离的特性。

小结

  1. template 的出现是为了解决 HTML 页面元素重复代码问题,让相同结构,不同数据的 HTML 代码可以复用。
  2. 需要注意,如果使用的是别的页面的节点,需要使用document.importNode进行导入后才可使用。该方法传入两个参数,第一个为节点,第二个是是否克隆该节点下的子节点。