使用同一聚合物自定义元素的多个实例
Use multiple instances of same polymer custom element
我在使用 polymer (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>
一点css到display/hide前面的svg元素
.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>
加载页面后,渲染完全正常。
当我将光标悬停在按钮上时,css 将不透明度设置为 1,迫使浏览器重绘按钮。
重新呈现按钮时,svg 图像的所有信息都使用最新声明的元素呈现(即本例中的 jenkins 按钮数据),但是 DOM 中的所有数据都是完美的商品,这在我看来很奇怪意见。
有人知道为什么浏览器将所有自定义元素渲染设置为最新的元素渲染还是错误?
我之前的测试是使用 Chrome 完成的,当我尝试使用 Firefox 时,情况更糟,所有元素都呈现第一个元素,但 DOM 中的数据很好。我错过了什么吗?
我认为你的问题是模式是全局的,而不是影子根的范围。我用 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 中的括号混淆了绑定系统,但也许我只是弄错了。 YMMV。不管怎样,计算函数可能是这样的:
_computeFill: function(name, id) {
return 'url('+ name + '-' + id + ')';
}
你可以让它更优雅一点,但这应该能让你工作。
这是部分解决方法,因为如果您重复使用 ID,您将回到最初的交换图像问题。
如果你想避免这种情况,你可以定义一个单独的模式库,由 ID 标识(就像 iron-iconset-svg
对图标所做的那样)。或者,作为更简单的解决方案,您可以根据 SVG 文件名计算一个唯一 ID。
希望对您有所帮助。
我在使用 polymer (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>
一点css到display/hide前面的svg元素
.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>
加载页面后,渲染完全正常。
当我将光标悬停在按钮上时,css 将不透明度设置为 1,迫使浏览器重绘按钮。 重新呈现按钮时,svg 图像的所有信息都使用最新声明的元素呈现(即本例中的 jenkins 按钮数据),但是 DOM 中的所有数据都是完美的商品,这在我看来很奇怪意见。
有人知道为什么浏览器将所有自定义元素渲染设置为最新的元素渲染还是错误?
我之前的测试是使用 Chrome 完成的,当我尝试使用 Firefox 时,情况更糟,所有元素都呈现第一个元素,但 DOM 中的数据很好。我错过了什么吗?
我认为你的问题是模式是全局的,而不是影子根的范围。我用 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 中的括号混淆了绑定系统,但也许我只是弄错了。 YMMV。不管怎样,计算函数可能是这样的:
_computeFill: function(name, id) {
return 'url('+ name + '-' + id + ')';
}
你可以让它更优雅一点,但这应该能让你工作。
这是部分解决方法,因为如果您重复使用 ID,您将回到最初的交换图像问题。
如果你想避免这种情况,你可以定义一个单独的模式库,由 ID 标识(就像 iron-iconset-svg
对图标所做的那样)。或者,作为更简单的解决方案,您可以根据 SVG 文件名计算一个唯一 ID。
希望对您有所帮助。