如何在Shadow DOM中不渲染<content>标签中的内容?

How to not render the content in the <content> tag in Shadow DOM?

我目前正在开发一个网络组件(使用 Polymer 构建),让我的元素的使用者将一些内容放入元素标签中,如下所示:

<my-element mode="fancy">
  <item>First item</item>
  <item>Second item</item>
  <item>Third item</item>
       <!-- ... -->
</my-element>

所以下一步是在我的元素定义中使用 <content>,如下一个片段所示,将内容投射到我的自定义元素中:

<template>
  <content id="idToHandleIt" select="item"></content>
</template>

现在的问题是,所有 item立即 呈现。但我不想在那里显示它们,因为我必须过滤我的组件 (JavaScript) 逻辑中的元素以获得更多标准,而不仅仅是我可以使用的 CSS-Selectors select 属性。

有没有人对这个问题有好的解决方案,或者有没有 API 让我有可能 grab distributed 节点?正如我现在尝试的那样,使用 getDistributedNodes() 的唯一方法是执行以下操作:

this.querySelector('idToHandleIt').getDistributedNodes();

但我总是需要 <content> 元素 :(

手动添加到 shadowRoot 怎么样?

<script src="http://www.polymer-project.org/webcomponents.min.js?20141211"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">

<polymer-element name="example-element">
  <template></template>
  <script>
    Polymer({

      ready: function() {
        var children = this.children;

        for (var i = 0; i < children.length; i++) {

          var childElement = children[i];

          if (childElement.hasAttribute("banana") && childElement.getAttribute("amount") > 0) {
            
            this.shadowRoot.appendChild(childElement);
            
            // we have to negate one from the index for each append to the shadowRoot
            i--;
            
          }

        }
      }

    });
  </script>
</polymer-element>

<example-element>
  <p banana amount="1">one banana</p>
  <p apple>one apple</p>
  <p banana amount="2">two banana</p>
  <p banana amount="3">three banana</p>
  <p banana amount="0">no banana</p>
</example-element>

幸运的是,您可以通过多种方式做到这一点,但您可能应该避免设置 <content> 本身的样式,因为它只是一个插入点。

但是,如果您想延迟实际插入,您可以将 <content>select 属性设置为 "isn't valid",如下所示:

<script src="http://www.polymer-project.org/webcomponents.min.js?20141211"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">

<polymer-element name="x-item" noscript>
  <template>
    <div>
      <content></content>
    </div>
  </template>
</polymer-element>

<polymer-element name="example-element">
  <template>
    <style>
      .container {
        opacity: 1;
        transition: all 1s linear;
      }
      [unresolved] {
        visibility: none;
        opacity: 0;
      }
    </style>
    <template if="{{counter > 0}}">They will appear after {{counter}}s.</template>
    <div unresolved?="{{counter > 0}}" class="container">
      <content id="idToHandleIt" select="{{counter > 0? 'nope' : 'x-item'}}"></content>
    </div>
  </template>
  <script>
    Polymer({
      counter: 5,
      ready: function() {
        this.countDown();
      },
      countDown: function() {
        if (this.counter <= 0) {
          return;
        }
        this.async(this.countDown, null, 1000);
        this.counter--;
      }
    });
  </script>
</polymer-element>

<example-element>
  <x-item>Item 1</x-item>
  <x-item>Item 2</x-item>
  <x-item>Item 3</x-item>
  <x-item>Item 4</x-item>
  <x-item>Item 5</x-item>
</example-element>