css之ShadowDOM

shadow-root 是用来表示一个元素的 Shadow DOM 根节点。Shadow DOM 是 Web 组件技术的一部分,它提供了一个封装的 DOM 和样式范围,使元素的内部结构和样式不会影响到外部文档,也不会被外部文档所影响。例如video标签.

定义

Shadow DOM 允许你创建一个与主文档 DOM 分离的 “影子” 树,这个树中的节点是完全封装的。这种封装提供了以下几个好处:

  1. 样式隔离:Shadow DOM 内部的样式和主文档的样式相互隔离。
  2. DOM 隔离:Shadow DOM 内部的 DOM 节点与主文档的 DOM 节点隔离,不会相互干扰。
  3. 可复用性:可以创建可复用的、自包含的组件。

当你在开发者工具中查看一个带有 Shadow DOM 的元素时,你会看到一个 #shadow-root 标记。这表示该元素有一个关联的 Shadow DOM。Shadow DOM 的内容会显示在 #shadow-root 的子树下。

创建shadowDom

步骤

  1. 定义一个自定义元素:使用 ES6 类继承 HTMLElement
  2. 附加 Shadow DOM:在自定义元素的构造函数中使用 this.attachShadow({ mode: 'open' }){ mode: 'closed' } 创建 Shadow DOM。
  3. 添加内容到 Shadow DOM:将元素和样式插入 Shadow DOM。

示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Shadow DOM Example</title>
</head>
<body>
    <!-- 自定义元素 -->
    <my-element></my-element>
    <script>
        // 定义一个新的类,继承自 HTMLElement
        class MyElement extends HTMLElement {
            constructor() {
                super();
                // 创建一个开放模式的 Shadow DOM
                const shadowRoot = this.attachShadow({ mode: 'open' });

                // 创建并添加样式到 Shadow DOM
                const style = document.createElement('style');
                style.textContent = `
                    .text {
                        color: red;
                        font-size: 20px;
                    }
                `;
                shadowRoot.appendChild(style);

                // 创建并添加内容到 Shadow DOM
                const div = document.createElement('div');
                div.className = 'text';
                div.textContent = 'Hello, Shadow DOM!';
                shadowRoot.appendChild(div);
            }
        }

        // 将自定义元素注册为一个新标签
        customElements.define('my-element', MyElement);
    </script>
</body>
</html>
  1. 定义类

    • 使用 class MyElement extends HTMLElement 定义了一个新的自定义元素类。
  2. 构造函数

    • 在构造函数中调用 super() 以确保正确继承。
    • 使用 this.attachShadow({ mode: 'open' }) 创建一个开放模式(open)的 Shadow DOM。
    • mode: 'open' 表示 Shadow DOM 是开放的,可以通过 JavaScript 进行访问。
    • mode: 'closed' 表示 Shadow DOM 是关闭的,无法通过 JavaScript 直接访问。
  3. 添加样式

    • 创建一个 style 元素,并将其添加到 Shadow DOM 中,以定义 Shadow DOM 内部元素的样式。
  4. 添加内容

    • 创建一个 div 元素,设置其文本内容和样式类,然后将其添加到 Shadow DOM 中。
  5. 注册自定义元素

    • 使用 customElements.define('my-element', MyElement) 将自定义元素注册为一个新标签 <my-element>

修改shadowDom样式

修改内联样式

document.addEventListener('DOMContentLoaded', () => {
	//获得shadowDom 的容器元素(宿主节点)
    const shadowHost = document.querySelector('your-shadow-host');
    //获得shadowDom 的根节点
    const shadowRoot = shadowHost.shadowRoot;
    //获得shadowDom 的内部子节点
    const targetElement = shadowRoot.querySelector('.my-element');
    
    if (targetElement) {
    	//修改样式
        targetElement.style.color = 'red';
        targetElement.style.backgroundColor = 'yellow';
    } else {
        console.error('Element not found in shadow DOM.');
    }
});

::part伪元素

只适用于 元素上已有 part 属性标记的暴露给外部样式表的部分
自定义的shadowDom使用::part,需要与part属性一起使用

示例代码

<style>
    /* 使用 ::part 选择器样式化 shadow DOM 内部的元素 */
    my-element::part(title) {
        color: blue;
        font-size: 24px;
    }
    my-element::part(content) {
        background-color: lightgrey;
        padding: 10px;
        border: 2px solid black;
    }
</style>
<body>
    <!-- 自定义元素 -->
    <my-element></my-element>
    <script>
        class MyElement extends HTMLElement {
            constructor() {
                super();
                const shadowRoot = this.attachShadow({ mode: 'open' });
                const style = document.createElement('style');
                //使用part属性,暴露给外部样式表
                style.textContent = `
                    .title {
                        part: title;
                        font-weight: bold;
                    }
                    .content {
                        part: content;
                    }
                `;
                shadowRoot.appendChild(style);

                const title = document.createElement('div');
                title.className = 'title';
                title.textContent = 'This is the Title';
                shadowRoot.appendChild(title);
                
                const content = document.createElement('div');
                content.className = 'content';
                content.textContent = 'This is the content of the custom element.';
                shadowRoot.appendChild(content);
            }
        }
        // 注册自定义元素
        customElements.define('my-element', MyElement);
    </script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值