我使用SVG和javascript。我想大量使用'use
元素来保持我的xml文件很小。
问题是我无法找到更改use
标记引用的元素的方法。请参阅我的代码示例:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" onload="init()" width="1000" height="900">
<defs>
<g id="test">
<circle cx="10" cy="20" r="20" fill="green" />
<line x1="10" y1="10" x2="100" y2="60" stroke="red" />
</g>
</defs>
<use xlink:href="#test" x="10" y="10" />
<use xlink:href="#test" x="50" y="50" />
<script type="text/javascript">
<![CDATA[
function init()
{
var allUses = document.querySelectorAll('[*|href="#test"]');
for (i = 0; i < allUses.length; i++) {
allUses[i].addEventListener('mouseover', testOver, false);
}
}
function testOver()
{
// on mouse over the element I want the circle the mouse goes over to change color to blue and the line to purple
// how to get a handle to the circle ???
//this.[get circle?]
}
function attribute(element, name, value)
{
element.setAttribute(name, value);
}
]]>
</script>
</svg>
如何获取use元素内部元素的句柄(基于每个'use tag')?
答案 0 :(得分:0)
没有简单的方法可以做你想做的事。 defs
和use
元素的固有特性决定了原始defs
元素中的子元素无法在从它派生的use
元素中单独操作。为此,需要每个use
元素具有每个子元素的单独副本。这将破坏defs
/ use
伙伴关系的其中一个目的,即节省内存。
但是,虽然您无法更改use
元素中某个特定子元素的属性,但您可以更改子所有的属性 - 一次use
元素中的元素。 (这种粗略控制是否足够取决于您的特定需求。)例如,复制其中包含多个形状的defs
元素时,您可以更改所有形状的填充颜色通过更改整个use
元素的填充颜色,在一个特定的use
元素中。这通过将moused-over use
元素的填充颜色更改为红色显示在下面的代码段中。但请注意,只有当您要更改的属性在原始defs
元素中指定而不是时才能执行此操作。下面的代码片段中显示了这样一个事实:您可以将use
元素中绿色圆圈的填充颜色更改为红色,而不是defs
元素中绿色的绿色。
实现我认为你想做的事情的一种方法是使用克隆。当您将鼠标悬停在特定use
元素上时,可以从defs
元素中克隆任何内容,将其放在use
元素中相应形状的顶部,然后更改该元素克隆/重新插入元素,但你想要的。每次将鼠标悬停在use
元素上并将其放回由use
元素的坐标引导的DOM中时,通过克隆第三个圆圈,可以在下面的代码片段中显示这一点。通过略微抵消克隆元素,我更容易看到这一点。当下一次鼠标悬停事件发生时,我也让它消失了,但是你是否想要这种行为取决于你的情况。 (请注意,将克隆元素放置在正确的位置在复杂文档中可能会非常棘手,特别是当组内有组并且已应用变换时,例如缩放,旋转,翻译。在这些情况下,您可能需要使用getCTM
/ getScreenCTM
。)
function init() {
var allUses = document.querySelectorAll('[*|href="#test"]');
for (i = 0; i < allUses.length; i++) {
allUses[i].addEventListener('mouseover', testOver, false);
}
}
function testOver() {
attribute(this, "fill", "red");
var circle3 = document.querySelector("defs").querySelector(".circle3").cloneNode(true);
var highlighted = document.querySelector("#highlighted");
highlighted.replaceChild(circle3, highlighted.childNodes[0]);
attribute(circle3, "fill", "blue");
var x = parseFloat(this.getAttribute("x")) + 4;
var y = parseFloat(this.getAttribute("y")) + 4;
attribute(circle3, "transform", "translate(" + x + "," + y + ")");
}
function attribute(element, name, value) {
element.setAttribute(name, value);
}
&#13;
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="en" onload="init()" width="450" height="150">
<defs>
<g id="test">
<circle class="circle1" cx="10" cy="20" r="20" fill="green" />
<circle class="circle2" cx="50" cy="20" r="20" />
<circle class="circle3" cx="90" cy="20" r="20" />
<circle class="circle4" cx="130" cy="20" r="20" />
</g>
</defs>
<use class="five" xlink:href="#test" x="10" y="10" fill="green" />
<use class="five" xlink:href="#test" x="50" y="80" fill="green" />
<g id="highlighted">
<g id="dummyElementToBeReplaced">
</g>
</g>
</svg>
&#13;