zoukankan      html  css  js  c++  java
  • Shadow DOM的理解

    Shadow DOM的理解

    Shadow DOMHTML的一个规范,其允许在文档document渲染时插入一颗DOM元素子树,但是这棵子树不在主DOM树中,Shadow DOM如果按照英文翻译的话可以翻译为影子DOM,是一种不属于主DOM树的独立的结构。

    描述

    Web components的一个重要属性是封装——可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净、整洁,在这里Shadow DOM接口是关键所在,它可以将一个隐藏的、独立的DOM附加到一个元素上,Shadow DOM标准允许你为你自己的元素custom element维护一组Shadow DOM
    Shadow DOM允许将隐藏的DOM树附加到常规的DOM树中,它以shadow root节点为起始根节点,在这个根节点的下方,可以是任意元素,和普通的DOM元素一样,另外还有一些Shadow DOM特有的术语。

    • Shadow host: 一个常规DOM节点,Shadow DOM会被附加到这个节点上。
    • Shadow tree: Shadow DOM内部的DOM树。
    • Shadow boundary: Shadow DOM结束的地方,也是常规DOM开始的地方。
    • Shadow root: Shadow tree的根节点。

    我们可以使用同样的方式来操作Shadow DOM,就和操作常规DOM一样——例如添加子节点、设置属性,以及为节点添加自己的样式(例如通过element.style属性),或者为整个Shadow DOM添加样式(例如在<style>元素内添加样式),不同的是Shadow DOM内部的元素始终不会影响到它外部的元素(除了:focus-within),这就为封装提供了便利。
    此外不管从哪个方面来看Shadow DOM都不是一个新事物,在过去的很长一段时间里,浏览器用它来封装一些元素的内部结构,以一个有着默认播放控制按钮的<video>元素为例,我们所能看到的只是一个<video>标签,实际上,在它的Shadow DOM中,包含来一系列的按钮和其他控制器。再举一个例子我们都知道像ReactVue这样的都有组件的概念,我们常用的<input><audio><video>等这些元素,其实它也是以组件的形式存在的,即HTML Web Component这些都有自己的Shadow DOM,这些组件内部是由自身的一些HTML标签组成的。
    现代浏览器FirefoxChromeOperaSafari等默认支持Shadow DOM,基于Chromium的新Edge也支持Shadow DOM,而旧Edge未能撑到支持此特性,至于IE浏览器嘛...,兼容性方面可以查阅此处https://caniuse.com/?search=Shadow%20DOM

    示例

    <!DOCTYPE html>
    <html>
    
    <head>
        <title>Shadow DOM</title>
        <style>
            .text{
                color: blue; /* 设置字体颜色 */ /* 可以看出在外部定义的样式无法影响到影子内部元素样式 */
            }
        </style>
    </head>
    
    <body>
        <div id="app">
            <div class="shadow-cls"></div>
        </div>
    </body>
    
    <script type="text/javascript">
        (function(doc, win){
            var shadowHost = doc.querySelector(".shadow-cls"); // 获取影子宿主shadow host
            var shadowRoot = shadowHost.attachShadow({mode: "open"}); // 创建(附加)影子shadow root // open 表示可以通过页面内的 JavaScript 方法来获取 Shadow DOM
            var style = doc.createElement("style"); // 创建style元素
            style.textContent = `
                .text{
                    font-style: italic;
                }
            `; // 影子内部样式
            const template = `
              <div>
                  <div class="text">Text</div>
              </div>
            `; // 模板 // 另外可以尝试 <template> 以及 <script text/template>
            const container = doc.createElement("div"); // 创建容器
            container.innerHTML = template; // 加入容器
            shadowRoot.append(style, container); // 加入影子
        })(document, window);
    </script>
    </html>
    

    每日一题

    https://github.com/WindrunnerMax/EveryDay
    

    参考

    https://segmentfault.com/a/1190000017970486
    https://www.cnblogs.com/tugenhua0707/p/10545179.html
    https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_shadow_DOM
    
  • 相关阅读:
    如何查看一个表的块使用状况
    esp8266烧录Html文件,实现内置网页控制设备!
    python一键电影搜索与下载
    基于 Vue BootStrap的迷你Chrome插件
    SpringBoot之自定义验证码
    iOS 图片部分模糊,类似于美图秀秀
    python实现的电影票房数据可视化
    坦克大战-C语言-详注版
    微信小程序-自定义底部导航
    微信小程序--搜索关键词高亮
  • 原文地址:https://www.cnblogs.com/WindrunnerMax/p/14389711.html
Copyright © 2011-2022 走看看