我正在使用Polymer,我注意到:target
css选择器无效。
例如
<polymer-element name="my-element" noscript>
<template>
<style>
:target {
border: 2px solid red;
}
</style>
<div id="test">This is a :target test</div>
</template>
</polymer-element>
<a href="#test">Click me</a>
<my-element></my-element>
我有什么建议可以解决这个问题吗?
答案 0 :(得分:2)
我必须承认:我不太熟悉影子DOM,并且绝对不熟悉Polymer,但我想告诉你我对此的看法,因为你的意图对我来说有点奇怪而且这个对于评论来说太长了。
您无法在影子主机中使用伪选择器:target
。
不幸的是,我无法在这些资源中找到明确的证据
但有些暗示......
Web Components的目标是让我们能够构建可以在文档中使用的单个和独立组件,而不必关心它们的内部功能或风格。
如果某个组件可以直接到达&#34;外部&#34;文档或外部文档可以直接到达任何影子主机元素,这将完全打破Web组件的意图。
想象一下如果插入<my-element>
的两个实例会发生什么。两者都包含相同的ID,哪一个应该被定位?
当然,您可以从影子文档中访问影子文档或包含文档,但只能分别通过::shadow
或:host
。
合乎逻辑的是,浏览器无法使用仅仅:target
选择器选择元素,因为目标是文档的问题(它的URL是针对某些ID的)而不是任何影子DOM。它也无法从容器文档中使用document.getElementById()
到达影子树节点。
同样贴近Shadow DOM概念的CSS scoping spec说明:
为什么影子主机如此奇怪?
影子主机位于影子树之外,其标记位于 控制页面作者,而不是组件作者。
如果组件使用特定的类名,那将是不太好的 内部在阴影树中,页面作者使用该组件 不小心也使用了相同的类名并将其放在主机上 元件。这种情况会导致意外造型 组件作者无法预测和混淆 页面作者调试。
(3.1.1. Host Elements in a Shadow Tree)
我说这是另一个证据:阴影主机(从外部看)本身将在处理树内的焦点时保持活动(焦点)状态。
为了保持封装,Document对象的值是焦点 必须调整API属性activeElement。防止丢失 调整此值时的信息,每个阴影根也必须具有 一个activeElement属性,用于存储焦点元素的值 影子树。
如果您的目的是仅突出显示div
,当您的阴影元素为:target
时,这可能是您的影子文档中的正确样式:
<polymer-element name="my-element" constructor="" attributes="">
<template>
<style>
:host(:target) #inner {
color: #0c0;
}
</style>
<content>Hello World!</content>
<div id="inner">This is a :target test</div>
...
当您的影子元素<div>
被<my-element id="outer"></my-element>
定位时,它会突出显示带有绿色文字的#outer
。
如果这不是您的意图,而您真的希望能够从外部定位#inner
,我说这是不可能的(请参阅&#34;更长的&#34;部分;)。
答案 1 :(得分:1)
我认为链接到影子dom中的元素是个好主意,因为你可能在同一个页面中有多个外部元素实例,这样你就可以获得具有相同id的多个元素
但是,当您使用#elementId
请求网址时,浏览器只会查看相应元素的光照dom。
如果你仍然需要设置阴影dom元素的样式,你可以模拟:target
选择器:
<polymer-element name="my-element" constructor="" attributes="">
<template>
<style>
#inner[target] {
border: 2px solid red;
}
</style>
<content>Hello World!</content>
<div id="inner" target?="{{innerTargetted}}">This is a :target test</div>
</template>
<script>
Polymer('my-element', {
ready: function() {
$(window).on('hashchange', function() {
this.innerTargetted = window.location.hash == '#inner';
}.bind(this));
}
});
</script>
</polymer-element>