我知道可以将普通的Javascript事件处理程序附加到SVG标记中的元素。我希望复制很多对象的实例,所以我打算使用<def>
和<use>
标签来简化一些事情。但是,我的每个孩子的物品都需要处理&#34;点击&#34;和其他事件。我可以为每个孩子定义那些事件,但如果我能以某种方式在初始项目中定义它们,那么这将是很好的,然后只需重复使用&#34;点击事件。这可能吗?
https://jsfiddle.net/khyp1o0w/
<svg width="400" height="400" viewBox="0 0 400 400">
<defs>
<rect id="someDef" x="0" y="0" width="60" height="30" fill="#f00" />
<!-- ^^ would like to define an event here... -->
</defs>
<use x="150" y="150" xlink:href="#someDef" />
<use x="250" y="250" xlink:href="#someDef" />
<!-- ^^ ... that is used by these guys -->
</svg>
编辑:添加示例SVG。
答案 0 :(得分:1)
use
元素定位的IIRC元素应该在内部复制到<use>
元素中,就像<use>
是iframe一样,并且内容被克隆。
因此,这意味着原始节点上附加的事件不会被复制到副本,除非此事件是节点标记的一部分(内联)。但是Chrome并没有真正遵循这里的规格,甚至没有让它成功......所以这里是FF的一个例子:
// this won't work
document.getElementById('someDef').addEventListener('click', function() {
this.setAttribute('stroke', randomColor());
});
&#13;
<svg width="400" height="400" viewBox="0 0 400 400">
<defs>
<script type="application/javascript">
function randomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[~~(Math.random() * 15)];
}
return color;
}
</script>
<!-- this will work in FF -->
<rect id="someDef" onclick="this.setAttribute('fill',randomColor())" x="0" y="0" width="60" height="30" fill="#f00" />
</defs>
<use x="150" y="150" xlink:href="#someDef" />
<use x="250" y="250" xlink:href="#someDef" />
</svg>
&#13;
你当然可以通过监听root svg元素上的click事件来使用事件委托,但是这只适用于直接目标元素,而不适用于嵌套目标元素:
var svg = document.querySelector('svg');
svg.addEventListener('click', function(e) {
var usedTargetID = e.target.getAttributeNS("http://www.w3.org/1999/xlink", 'href');
switch (usedTargetID) {
case '#direct':
clickDirect(e);
break;
case '#nested':
clickNested(e);
break;
default:
return;
}
});
function clickDirect(e) {
// what you seem to want
e.target.setAttribute('fill', randomColor());
}
function clickNested(e) {
// will set both nested...
e.target.setAttribute('fill', randomColor());
}
function randomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[~~(Math.random() * 15)];
}
return color;
}
&#13;
<svg width="400" height="400" viewBox="0 0 400 400">
<defs>
<rect id="direct" x="0" y="0" width="60" height="30" />
<g id="nested">
<!-- you can only access this -->
<!-- not its content individually -->
<rect x="80" y="0" width="60" height="30" />
<rect x="20" y="70" width="60" height="30" />
</g>
</defs>
<use x="150" y="50" xlink:href="#direct" />
<use x="250" y="150" xlink:href="#nested" />
</svg>
&#13;
具有相同的限制