:目标css选择器不在聚合物中工作

时间:2014-12-27 21:20:20

标签: javascript css3 polymer

我正在使用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>

DEMO

我有什么建议可以解决这个问题吗?

2 个答案:

答案 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属性,用于存储焦点元素的值   影子树。

6.3 Active Element


解决问题的一种可能方法

如果您的目的是仅突出显示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>

Demo