首先我想说我知道这个问题类似于:
如何让导入的css字体/图标对shadow dom中的元素产生影响?
事实并非如此,也没有帮助。
问题:我最近决定使用 ShadowDOM 来封装我的项目中的样式。一开始我认为它按预期工作,但我注意到一些来自外部 CSS 文件的图标消失了。重要的是要注意,这些样式是外部的,并且进行更改的可能性是有限的。
我已经准备了代码来演示该问题(请参阅下面的代码片段)。
一切似乎都工作正常,除了 @font-face
正如您所看到的,包含带图标的外部 CSS 文件的 HTML 在 ShadowDOM 之外按预期工作。我也想在 ShadowDOM 中使用它。
我怎样才能做到这一点?
注意:如果您检查开发工具,网络选项卡中的 CSS 路径存在问题,但这是 SO 片段问题。如果您在本地运行该代码片段,则网络中一切正常。
const body = document.getElementsByTagName('body')[0];
const wrapper = document.querySelector('.wrapper')
const handleAddToShadowClick = (param) => {
const host = document.querySelector('#shadowHost');
if(param === 'insideShadow') {
const shadowRoot = host.attachShadow({mode: 'open'});
shadowRoot.innerHTML = firstComponent
} else {
const shadowRoot = host;
wrapper !== null ? body.removeChild(wrapper): ''
shadowRoot.innerHTML = firstComponent
}
}
const firstComponent = …Run Code Online (Sandbox Code Playgroud)我有一个 Web 组件,可以在 Shadow dom 中呈现以下内容:
<custom-banner>
#shadow-root
<div part="headertext">
I am the header text!
</div>
...
</custom-banner>
Run Code Online (Sandbox Code Playgroud)
要设置 的样式headertext,以下 css 效果很好:
custom-banner::part(headertext) {
border: 5px solid green;
}
Run Code Online (Sandbox Code Playgroud)
现在说我有这样的东西:
<custom-banner>
#shadow-root
<div part="headertext">
I am the header text!
<span>I am the subheader text!</span>
</div>
...
</custom-banner>
Run Code Online (Sandbox Code Playgroud)
有没有办法针对阴影部分的孩子?也就是说,像这样的东西(这似乎不起作用):
custom-banner::part(headertext) span {
border: 5px solid red;
}
Run Code Online (Sandbox Code Playgroud)
我意识到这种事情可能会削弱 的整个目的::part,但也许不会?
需要明确的是,在此示例中,子标题范围不是带槽子项。它始终是组件的一部分,并且位于Shadow dom 中。上面的示例是在浏览器中渲染的组件。
谢谢!
我有一个带有 的 div position: fixed,假设它应该附加到视口的底部而不是滚动,至少根据MDN是这样。
相反,我得到的是一个 div,它卡在其初始位置(渲染页面时视口的底部),但随后使用 Shadow-dom 滚动器上下滚动。
编辑:
这是一个 codepen,其元素位于核心支架内。请注意,这支笔中的红色 div 的位置:固定,如下面我的代码中所述。
http://codepen.io/ericeslinger/pen/bdedgp
这是一个 codepen,其元素位于核心支架之外。这是我想要的行为,但 div 在结构上位于核心支架内部(出于角度范围的原因)。
http://codepen.io/ericeslinger/pen/jPrPyy
FWIW,我使用的是聚合物 0.5。这是我正在运行的草图:
<head>
<style type="text/css">
.testClass {
position: fixed;
z-index: 1000;
bottom: 0;
left: 0px;
right: 0px;
height: 150px;
background-color: red;
}
</style>
</head>
<body unresolved>
<core-scaffold>
<div main vertical layout>
<span>woo</span>
<div class="testClass">This is some stuff at the bottom</div>
<div style="min-height: 2000px" flex></div>
</div>
</core-scaffold>
Run Code Online (Sandbox Code Playgroud)
如果我将 testClass div 移到 core-scaffold 之外,它会执行预期的操作并粘在窗口底部。如果我将其保留在核心支架内,则不会。
这个问题适用于 Ionic,但它的答案可以更普遍地适用于 CSS。我不知道。
我使用 ionic 4 创建具有特定样式的影子 DOM 元素。我有以下内容:
<ion-item>
<ion-label position="floating">Floating Label</ion-label>
<ion-input></ion-input>
</ion-item>
Run Code Online (Sandbox Code Playgroud)
我希望“浮动标签”文本在浮动时比平时更向左移动。我可以使用标签本身的样式轻松地做到这一点。
然而,在其下创建的 Shadow DOM divion-item有自己的样式,其中包括overflow: hidden. 我还没有找到从样式表更新这些样式的方法。我尝试过使用/deep/和各种其他选择器,但这些似乎不起作用,并且对它们的支持似乎也被删除了。我知道您可以使用 CSS 变量,但这个特定属性overflow不是由变量设置的。我还知道您可以使用 DOM 将样式注入到影子 DOM 中,但我想避免这样做,因为我必须在每个组件中的某个地方执行此操作,而不是能够在整个应用程序中执行一次。
如果变量不可用,是否有任何方法可以使用 CSS 覆盖影子 DOM 中设置的样式?
在此版本之前,“-internal”伪元素在 CSS 中运行良好。但是他们在最后一个版本中弃用了它们,所以如果我像这样在 CSS 中设置:
video::-internal-media-controls-overflow-button{
display: none;
}
Run Code Online (Sandbox Code Playgroud)
它适用于以前的版本,但应该随该弃用而更改的本机视频播放器的阴影元素仍然相同。检查此屏幕截图
视频的shadowroot是关闭的,所以我无法通过JS访问删除或隐藏。
我想他们应该将那些 -internal 伪元素切换到 -webkit,但目前我找不到其他解决方案。
任何的想法?
我刚刚遇到了一个有趣的情况,我<button>在放置在<form>.
<form id="one" action="" method="get">
<s-button>Select</s-button>
#shadow-root
<button>...</button>
<button>Outside</button>
</form>
Run Code Online (Sandbox Code Playgroud)
我也有一个<button>作为<form>.
孩子<button>导致表单提交。
但是<button>在 shadow-root 中没有。
在某种程度上,我想这是有道理的。但是有没有人想出一种方法来告诉 shadow-root<button>正常工作,<form>或者这是我必须通过 JS 处理的事情?
我知道单击事件在 Shadow DOM 层被阻止,但我很惊讶没有办法让按钮仍然是表单的一部分,可以通过属性或属性设置的东西。
当然,我可以捕获点击事件,然后从中发送一个新的事件,this但这不会做同样的事情,因为我的事件将不再是用户生成的,并且有大量与之相关的规则。
我有两个网络组件,一个类似于列表项,另一个是容器。在列表项中有一个按钮,它调度 onclick 事件。两个组件都使用独立的 Shadow-dom。
<custom-list>
<custom-list-item></custom-list-item>
<custom-list-item></custom-list-item>
<custom-list-item></custom-list-item>
</custom-list>
Run Code Online (Sandbox Code Playgroud)
如何在“自定义列表”中侦听“自定义列表项”中的按钮发出的事件?
我们使用 Angular 8 的自定义元素创建了一个 Web 组件。该组件的一部分是显示一些自定义图标(作为不同的应用程序开发和打包)。正如您在上一个问题中所看到的,我们已经成功地将所有 css 捆绑在一个文件中,并使用但不使用 Shadow DOM 在独立应用程序中显示它们:host ::ng-deep。
在我的 Web 组件中切换到 Shadow DOM ( encapsulation: ViewEncapsulation.ShadowDom) 并删除即将弃用的字体后::ng-deep,应用程序中的字体似乎已损坏。
我在这里和这里找到的唯一解决方案表明字体声明必须发生在shadowDOM之外,例如包含自定义组件js文件(作为独立应用程序)的html文件内。就我而言,字体被打包为不同的应用程序,并且自定义 Web 组件将在许多采用不同技术的项目中使用,而这些项目可能无法包含它。
自定义图标(@font-face)是否有另一种方法可以在影子 DOM 中工作?
我正在使用 Vue 和 Bootstrap 作为应用程序,根据官方 Vue 文档(https://cli.vuejs.org/guide/build-targets.html#web-component)生成 Web 组件。大多数情况下,Bootstrap 和我的业务逻辑在#shadow-rootWeb 组件中运行良好,就像在轻量级 DOM 中一样。
然而,Bootstrap 工具提示(基于 Popper.js https://popper.js.org/)在 Shadow DOM 中根本不起作用。我还尝试在 Shadow DOM 封装代码中直接使用 Popper.js 和 Tippy.js ( https://atomiks.github.io/tippyjs/ ) 调用工具提示,完全避开 Bootstrap,但我仍然无法让它们工作。
请参阅此处的示例: https: //jsfiddle.net/mfep6rg9/
我可以猜测为什么——第 3 方工具提示库很可能找不到目标 DOM 元素,因为它位于 Shadow DOM 中。
是否有第三方解决方案可以解决 Shadow DOM / Web 组件封装问题?
在使用 Playwright(或 Puppeteer)编写 E2E 测试时,我使用 Chrome 开发工具来检查我的 css 选择器。
为了验证选择器是否有效并且可以找到,我在 DevTools 的 Elements-Tab 中使用 cmd+f 搜索栏,如下所示:
但是如何在 Shadow-root 中找到选择器呢?
只是为了明确:这个选择器可以通过代码找到。我只是在 DevTools 中找不到它
shadow-dom ×10
css ×5
javascript ×5
angular ×2
font-face ×1
html ×1
html5-video ×1
icon-fonts ×1
polymer ×1
tooltip ×1
vue.js ×1