我正在为我们公司编写RIA系统(仅限铬)。不同控件的数量正在增长,我决定使用Shadow DOM简化代码。它很棒,但有时它需要外部重新造型。这就是问题,例如:
任务栏:
<taskbar side="right">
<menubtn />
<applist scrollable>
<btn app="SpoPlanMon" />
</applist>
<tray />
</taskbar>
使用Shadow DOM,applist转换为:
<applist>
<scroll-wrap>
<scroll-bar>
<scroll-slider />
</scroll-bar>
<scroll-cont>
<btn app="SpoPlanMon" />
</scroll-cont>
</scroll>
</applist>
在这种情况下,我需要根据<scroll-slider />
侧(在所谓的属性中指定,可以动态更改)来设置<taskbar />
样式。不幸的是,我不能只写taskbar[side="top"] scroll-slider {...}
,因为只允许低边界封装。
有没有办法从“另一边”css选择元素?或者像video::-webkit-media-controls-panel
?
答案 0 :(得分:1)
如果您使用的是成熟的Web Components而不是Shadow DOM,那么您应该能够从Javascript获取父任务栏元素。像这样:
<element>
<template>
...
</template>
<script>
if (this !== window) {
this.lifecycle({
created: function() {
this.parentElement.attributes['side'].nodeValue; // "right"
}
});
}
</script>
</element>
然而,这使得您无法再在任务栏之外使用applist组件,这通常是一件坏事。我们应该尝试使组件尽可能模块化,独立和可重用。问问自己,“我究竟需要了解哪些父元素?”您可以改为将应用列表写为
<applist scrollable="right">...
为了在任何地方使用此组件的能力,复制是一个很小的代价。谁知道?将来,您可以决定使用side="right"
但scrollable="bottom"
的方式使用任务栏和应用列表!
<强>更新强>
如果您希望允许Shadow DOM元素的样式随主机元素的更改而动态更改,您很快就可以使用@host @-rule。规范在这里根本不清楚,但我认为它会像这样使用(取自a comment on a bug for the W3 spec for Web Components):
@host {
div { background-color: white; }
.warning { background-color: yellow; }
.important .warning { background-color: orange; }
}
这会(我认为)为主机提供白色的默认背景颜色,如果主机具有类warning
,则会将其覆盖为黄色。它还会在主机内部设置警告元素,背景颜色为橙色,如果主机具有类important
。
答案 1 :(得分:1)
您可以使用CSS变量将左/右上下文传递到滑块。有关工作示例,请参阅this jsfiddle。 (您必须在Chrome中启用启用实验性WebKit功能标记。)
以下是它的工作原理:外部组件为每个依赖于上下文的属性设置变量(在这种情况下,在左侧或右侧)。在这个例子中,我只是设置一个变量,一个颜色:
<style>
*[side="right"] {
-webkit-var-slider-color: red;
}
*[side="left"] {
-webkit-var-slider-color: green;
}
</style>
<taskbar side="right">
<menubtn />
<applist scrollable>
<btn app="SpoPlanMon" />
</applist>
</taskbar>
该组件只使用变量:
<applist>
<style>
scroll-slider {
background: grey; /* default */
background: -webkit-var(slider-color);
}
</style>
<scroll-wrap>
<scroll-bar>
<scroll-slider />
</scroll-bar>
<scroll-cont>
<btn app="SpoPlanMon" />
</scroll-cont>
</scroll>
</applist>
在此示例中,<taskbar side="right">
元素将slider-color变量设置为红色。 CSS变量自动流入Shadow DOM,因此在applist中,滚动滑块的背景设置为红色。如果您将任务栏更改为side =“left”,则会重新计算样式,并且滚动滑块的背景会自动翻转为绿色。
如果要配置更多属性,只需使用更多变量。
在使用它的地方定义属性的目的
background: grey; /* default */
background: -webkit-var(slider-color);
是处理未设置变量的情况。在这种情况下,第二个属性定义将无效,导致它被删除,因此第一个属性定义适用。正确设置变量后,第二个定义有效并覆盖第一个定义。
关于CSS变量的简洁部分是它们与定义变量的元素一起嵌套。因此,如果SpoPlanMon Shadow DOM中有<taskbar side="left">
,它会将slider-color变量重置为绿色,嵌套在其中的任何滑块都将为绿色。
有一个设计方案允许Web组件使用作者定义的伪ID将shadow DOM中的部件暴露给“来自外部”的样式。 (W3 Bug 15196并不是非常具有描述性,但这是规范错误。)
要使用伪ID解决此问题,AppList会使用伪ID公开其滚动滑块:
<applist>
<scroll-wrap>
<scroll-bar>
<scroll-slider pseudo="slider" />
</scroll-bar>
<scroll-cont>
<btn app="SpoPlanMon" />
</scroll-cont>
</scroll>
</applist>
然后任务栏可以设置样式:
<taskbar side="right">
<style scoped>
taskbar[side="right"] applist:pseudo(slider) {
/* styles apply to the <scroll-slider> */
}
</style>
<menubtn />
<applist scrollable>
<btn app="SpoPlanMon" />
</applist>
<tray />
</taskbar>
这很好,因为它将任务栏上下文的样式与任务栏一起保存。应用程序列表需要在其滑块上放置一个伪,因此如果你重复使用一个没有为你需要设置样式的所有内容的组件,你就会遇到麻烦(CSS很强大,所以它带来很大的功能来搞砸了,所以我认为组件通常不会暴露很多伪ID。)
这没有实现,甚至在规格中!事实上,确切的语法可能会改变。所以现在你不能依赖伪ID解决方案。 CSS变量可能是要走的路。