其他分享
首页 > 其他分享> > shadow DOM 影子DOM

shadow DOM 影子DOM

作者:互联网

shadow DOM有以下特点:

总结起来就是,shadow DOM可以把一部分html代码隔离起来,与外部完全不会互相干扰。

影子dom 就像封装了一个标签组件,大部分样式都默认隐藏了.

Shadow DOM 它是HTML的一个规范,它允许在文档(document)渲染时插入一颗DOM元素子树,但是这个子树不在主DOM树中。
它允许浏览器开发者封装自己的HTML标签、css样式和特定的javascript代码、同时开发人员也可以创建类似 <input>、<video>、<audio>等、这样的自定义的一级标签。创建这些标签内容相关的API,可以被叫做 Web Component。

示例一

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>shadow DOM</title>
    <style>
      body {
        background-color: #f3f3f3;
      }
      .text {
        color: red;
      }
    </style>
  </head>
  <body>
    <input type="text" placeholder="请输入内容" />
    <div id="div1"><p class="text">这是外面页面的text类文字</p></div>

    <div id="div2">
      <p class="text">这是原本就在html上的dom元素,3秒后添加到shadow-host里</p>
    </div>
    <div id="shadow-host">
      <p>这是shadow-host下的,与shadow-root平级的兄弟元素,将不会显示</p>
    </div>
  </body>
  <script>
    function addShadow() {
      const shadowHost = document.querySelector("#shadow-host");
      // 通过attachShadow创建一个shadow Root
      const shadow = shadowHost.attachShadow({ mode: "open" });

      const shadowDiv = document.createElement("div");
      shadowDiv.setAttribute("class", "texts");
      shadowDiv.innerText = "shadow DOM内部的text类文字";

      // 为shadow dom创建一个style标签,一开始这个style.isConnected为false,把他添加给shadow Root后 isConnected就为true了
      const style = document.createElement("style");
      let newdom = document.createElement("div");
      newdom.setAttribute("class", "new");
      newdom.innerText = "新添加的shadow dom文本";
      let newdp = document.createElement("div");
      newdp.setAttribute("class", "newdp");
      newdp.innerText = "新添加的子节点shadow dom文本,我还会变色";
      style.textContent = `
        .texts {
          color: green
        }
        .new {
          color: blue
        }
        .newdp{
          color:#ff6700
        }
      `;
      // 为shadow dom添加元素
      shadow.appendChild(style);
      console.log(style.isConnected);

      shadow.appendChild(shadowDiv);

      console.log(document.querySelectorAll(".text"));
      console.log(shadow.querySelectorAll(".text"));

      setTimeout(() => {
        shadow.appendChild(document.querySelector("#div2"));
        shadow.appendChild(newdom);
        newdom.appendChild(newdp);
        setTimeout(() => {
          // 将外部引用的样式添加到 Shadow DOM 上
          const linkElem = document.createElement("link");
          linkElem.setAttribute("rel", "stylesheet");
          linkElem.setAttribute("href", "index.css");
          // 将所创建的元素添加到 Shadow DOM 上
          shadow.appendChild(linkElem);
        }, 1000);
      }, 3000);
    }

    setTimeout(() => {
      addShadow();
    }, 2000);
  </script>
</html>

重点知识js引用外部css样式

     
//css文件跟当前文档在同一目录即可     
// 将外部引用的样式添加到 Shadow DOM 上
const linkElem = document.createElement("link");
linkElem.setAttribute("rel", "stylesheet");
linkElem.setAttribute("href", "index.css");
// 将所创建的元素添加到 Shadow DOM 上
shadow.appendChild(linkElem);

实例二

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>shadow DOM</title>
    <style>
      .text {
        color: red;
      }
    </style>
  </head>
  <body>
    <div id="div1"><p class="text">这是外面页面的text类文字</p></div>

    <div id="div2">
      <p class="text">这是原本就在html上的dom元素,3秒后添加到shadow-host里</p>
    </div>
    <div id="shadow-host">
      <p>我一秒以后消失</p>
    </div>
  </body>
  <script>
    //结论就是html的样式即使和shadow内部样式重名了也不会相互影响
    function addShadow() {
      const shadowHost = document.querySelector("#shadow-host");
      // 通过attachShadow创建一个shadow Root
      const shadow = shadowHost.attachShadow({ mode: "open" });

      const shadowDiv = document.createElement("div");
      shadowDiv.setAttribute("class", "text");
      shadowDiv.innerText = "shadow DOM内部的text类文字";
      let style = document.createElement("style");
      shadow.appendChild(shadowDiv);
      style.textContent = `
      .text{
        color:blue
      }
      `;
      shadow.appendChild(style);
      console.log(document.querySelectorAll(".text"));
      console.log(shadow.querySelectorAll(".text"));

      setTimeout(() => {
        shadow.appendChild(document.querySelector("#div2"));
      }, 3000);
    }
    setTimeout(() => {
      addShadow();
    }, 1000);
  </script>
</html>

mode

可以使用 Element.attachShadow() 方法来将一个 shadow root 附加到任何一个元素上。它接受一个配置对象作为参数,该对象有一个 mode 属性,值可以是 open 或者 closed

open 表示可以通过页面内的 JavaScript 方法来获取 Shadow DOM,例如使用 Element.shadowRoot 属性:

自定义元素

customElements.define()方法用来注册一个 custom element,该方法接受以下参数:

发送

otherWindow.postMessage(message, targetOrigin, [transfer]);

接收

接收时的message 的属性有:

示例三

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>shadow DOM</title>
  <style>
    .text {
      color: red;
    }
  </style>
</head>

<body>
  <z-div text="我是原信息"></z-div>
  <button onclick="sendMsg()">发送事件</button>
  <script defer>
    class ZDiv extends HTMLElement {
      constructor() {
        // 必须首先调用 super 方法
        super();
        const shadow = this.attachShadow({
          mode: "open"
        });
          
        const shadowDiv = document.createElement("div");
        shadowDiv.innerText = this.getAttribute("text");
        shadow.appendChild(shadowDiv);

        window.addEventListener(
          "message",
          function (event) {
            console.log(event);
            shadowDiv.innerText =
              event.origin + " 发来信息:\n " + JSON.stringify(event.data);
          },
          false
        );
      }
    }
    customElements.define("z-div", ZDiv);

    function sendMsg() {
      window.postMessage({
        time: new Date().toLocaleString(),
        url:"www.baidu.com"
      });
      }
  </script>

</html>

 

标签:影子,style,DOM,text,shadowDiv,shadow,document
来源: https://www.cnblogs.com/guozhongbo/p/15928207.html