使用相同聚合物自定义元素

时间:2016-03-17 22:12:33

标签: polymer polymer-1.0 multiple-instances

我在使用聚合物(1.3.1)定义自定义元素时遇到问题,该元素是Portal webapp的svg按钮。

这是我的自定义元素的代码:

<link rel="import" href="../../lib/polymer/1.3.1/polymer.html">

<dom-module id="portal-button">
  <link rel="import" type="css" href="portal-button.css">
  <template>
    <svg id="hexagon-button" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="200" height="187">
      <a xlink:href="#dummy" xlink:href$="{{url}}">
        <defs>
          <pattern id="dashed-line" height="9" width="9" patternUnits="userSpaceOnUse">
            <rect x="0" y="0" width="9" height="9" fill="rgb(245,245,245)" />
            <line x1="1" y1="9" x2="9" y2="1" stroke="rgb(187,187,187)" stroke-dasharray="2" />
          </pattern>
          <pattern id="logo" width="100%" height="100%" viewBox="0 0 135 133">
            <image id="buttonlogo" width="135" height="133" xlink:href="#dummy" xlink:href$="{{src}}" />
          </pattern>
          <pattern id="text" width="100%" height="100%" viewBox="0 0 590 76">
            <image id="buttontext" width="590" height="76" xlink:href="#dummy" xlink:href$="{{text}}" />
          </pattern>
        </defs>
        <g class="button">
          <g class="back">
            <path d="M 150,13 L 50,13 0,100 50,187 150,187 200,100 z M 140,31 L 60,31 20,100 60,169 140,169 180,100 z" fill-rule="evenodd" fill="url(#dashed-line)" />
            <polygon points="140,31 60,31 20,100 60,169 140,169 180,100" fill="rgb(88,151,162)" />
            <polygon points="140,31 60,31 20,100 60,169 140,169 180,100" fill="url(#logo)" />
          </g>
          <g class="front">
            <polygon points="19,100 25,90 175,90 181,100 175,110 25,110" fill="url(#dashed-line)" />
            <polygon points="19,100 25,90 175,90 181,100 175,110 25,110" fill="url(#text)" />
          </g>
        </g>
      </a>
    </svg>
  </template>
</dom-module>

<script>
  Polymer({
    is: 'portal-button',

    properties: {
      text: String,
      url: String,
      src: String
    }
  });
</script>

显示/隐藏前svg元素的一点css

.back {
	fill-opacity: 0.5;
}

.front {
	fill-opacity: 0.1;
}

.button:hover > * {
	fill-opacity: 1;
}

index.html,声明了我的自定义元素的两个实例

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Izakiel's Lair</title>
  <link rel="icon" href="chaos_symbol.png">
  <!-- include polymer html5 polyfill library -->
  <script src="lib/webcomponentsjs/0.7.21/webcomponents-lite.js"></script>
  <link rel="import" href="components/portal-button/portal-button.html">
</head>

<body>
  <portal-button id="virtualmin" url="http://localhost:8080/portal" src="img/virtualmin-logo.svg" text="img/virtualmin-titles.svg"></portal-button>
  <portal-button id="jenkins" url="http://localhost:8080/portal" src="img/jenkins-logo.svg" text="img/jenkins-titles.svg"></portal-button>
</body>

</html>

加载页面时,渲染完全正常。

page loaded

当我将光标悬停在按钮上时,不透明度由css设置为1,强制浏览器重绘按钮。 当重新渲染按钮时,svg图像的所有信息都使用最新声明的元素(即本例中的jenkins按钮数据)进行渲染,但是我认为DOM中的数据完全是物品,这在我看来很奇怪。 p>

after hover

有人知道为什么浏览器会使用最新的元素渲染设置所有自定义元素渲染,还是一个错误?

我以前的测试是使用Chrome完成的,当我尝试使用Firefox时甚至最糟糕的是,所有元素都具有第一个元素的渲染,但DOM中的数据是好的。我错过了什么吗?

firefox example

1 个答案:

答案 0 :(得分:1)

我认为你的问题是模式是全局的,而不是作用于影子根。我用shady DOM和native shadow root尝试了这个,结果相同。

这是解决Chrome和Firefox上的直接问题的部分解决方法:为每种模式创建唯一ID:

<pattern id="logo-{{id}}" width="100%" height="100%" viewBox="0 0 135 133">
  <image id="buttonlogo" width="135" height="133" xlink:href="#dummy" xlink:href$="{{src}}" />
</pattern>

应用这样的模式:

<polygon points="140,31 60,31 20,100 60,169 140,169 180,100" fill$="[[_computeFill('#logo', id)]]" />

我发现我需要一个计算绑定 - 我认为url( arg中的parens混淆了绑定系统,但也许我只是出了点问题。因人而异。无论如何,计算功能可能如下所示:

_computeFill: function(name, id) {
  return 'url('+ name + '-' + id + ')';
}

你可以让它更优雅,但这应该让你工作。

这是部分解决方法,因为如果您重新使用ID,您将回到交换图像的初始问题。

如果你想避免这种情况,你可以定义一个单独的模式库,由ID标识(如iron-iconset-svg用于图标)。或者作为一个更简单的解决方案,您可以从SVG文件名计算唯一ID。

希望这有帮助。