我对Web组件的理解是,您可以使用它来防止从Web组件到父组件的CSS泄漏.我需要的正是这一点,但出于某种原因,Web组件中的样式会影响整个文档.

我现在的配对伙伴(ChatGPT)也不明白发生了什么,?.

    <template id="test-shadow-dom-template">
        <slot name="menu-bar"></slot>
        <span id="contents">
            <slot>The content</slot>
        </span>
    </template>
   <script type="text/javascript">
        if(!customElements.get('test-shadow-dom')) {
            customElements.define('test-shadow-dom', class extends HTMLElement {
                constructor() {
                    super();

                    let template = document.getElementById("test-shadow-dom-template");
                    let templateContent = template.content;

                    const shadowRoot = this.attachShadow({mode: 'open'});
                    shadowRoot.appendChild(templateContent.cloneNode(true));
                }
            });
        }
    </script>
<div id="test-shadow-dom-container" class="box" style="height: 100%">
    <test-shadow-dom id="my-id">
        <style>
            * {
                font-style: italic;
            }
        </style>
        <h1>Here is the actual contents...</h1>
    </test-shadow-dom>
</div>

Chrome开发人员工具

Chrome developer tools

我的理解是,只有test-shadow-dom的内容是斜体的,而网页上的所有内容都是italic.

知道这是怎么回事吗?

推荐答案

my long explanation on ::slotted

Slotted content remains in lightDOM, it is reflected to shadowDOM <slot>
it is NOT moved to shadowDOM <slot>.

因此,您的<style>将设置全局文档的样式,就像放置在<div>中时一样

Note inheritable (global) styles (see long ::slotted post) DO style shadowDOM.
font-style IS an inheritable style.

你可以把<style>放在<template>里面;我为了方便起见而省略了它.

还请注意,slotted <style>不会设置它所在的shadowDOM的样式(红色边框)

<div class="foo">This is my-element:</div>

<my-element>
  <style>
  * { /* in lightDOM, styles all of global DOM */
    font-style: italic; 
  }
  </style>
  <style>
    div {
      border: 2px solid red;
    }
  </style>
  my-element
</my-element>

<script>
customElements.define("my-element", class extends HTMLElement {
    constructor() {
        super()
            .attachShadow({ mode: "open" })
            .innerHTML = `<style>
                            * { /* in shadowDOM, styles only shadowDOM */
                              color:green;
                              font-weight: bold; 
                            }
                          </style>
                          <div>Hello!</div>
                          <slot></slot>`;
    }
})
</script>

您确实可以控制用户放入lightDOM中的内容,但只有在解析完所有这些元素(在lightDOM中)之后,才能从connectedCallback中访问这些元素.

假设lightDOM不是很大(比如500多个元素),那么一个基本的setTimeout就足以在解析后延迟和执行代码:

connectedCallback() {
  setTimeout( () => {
    console.log( this.innerHTML );
  });
}

Html相关问答推荐

springBoot + Thymeleaf:基于Locale设置页面语言

如何在不影响子列表的情况下在HTML(OL Li)上同时加数字和列表?

如何在css中将包含多行文本的多个p-tag放在一起(并排)?

禁用与行分开的边框折叠span

让多对图像在各自的div中叠加

在将DevExtreme升级到版本23.2之后,到处都会生成一个Pesudo类,我在其中使用了<;DXi-Item Title=&Quot;&Quot;>;

OnChange函数未在下拉列表中使用一个选项触发

Html视频标签:圆角像素化

带有图标和悬停过渡的CSS按钮

如何使用css横向显示英文和中日韩文字?

在css中是否可以在遮罩图像中结合线性渐变和径向渐变?

禁用所有行,但在16角中单击编辑按钮的行除外

当多个a元素用作目标时的:target伪类

:after 伪元素没有出现,即使它有 content 属性

如何实现与内嵌图像对齐的自动换行?

当我希望它只横向滚动时,可滚动菜单也会上下移动

我正在try 向我预先存在的导航栏添加响应式汉堡包导航,但由于某种原因它没有显示

将固定/绝对伪元素放置在相对 div(具有滚动条)内,始终位于底部

是否有一种静态方式可以根据暗模式 Select 一张或另一张图像?

用 flexbox 和 overflow 覆盖