使用JavaScript,我可以更改SVG <g>元素的Z索引/图层吗?</g>

时间:2009-01-27 02:11:12

标签: javascript svg

假设我有几个复合形状(<g>)。我希望能够点击并拖动它们,但是我希望我碰巧在Z顺序中将其拖动到另一个的TOP上,这样如果我将它拖到其他的那个上,那么另一个一个人应该黯然失色。

9 个答案:

答案 0 :(得分:108)

SVG中的Z索引由元素在文档中出现的顺序定义。如果要将特定形状置于顶部,则必须更改元素顺序。

答案 1 :(得分:31)

在树中移动元素的替代方法是使用<use>元素更改xlink:href属性,以便为您提供所需的z顺序。

这是一个关于svg-developers邮件列表的old thread,在想要动画某些形状的上下文中讨论这个主题。

<强>更新

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
     style="width:100%; height: 100%">
    <circle id="c1" cx="50" cy="50" r="40" fill="lime" />
    <rect id="r1" x="4" y="20" width="200" height="50" fill="cyan" />
    <circle id="c2" cx="70" cy="70" r="50" fill="fuchsia" />
    <use id="use" xlink:href="#c1" />
</svg>

在此示例中&lt; use&gt; element是最后一个,它使它成为最前面的元素。只需更改xlink:href属性,我们就可以选择任何其他元素作为最前面的元素。在上面的示例中,我们选择了带有id="c1"的圆圈,这使其显示为最顶层的元素。

请参阅fiddle

答案 2 :(得分:21)

这是一个老问题,但是......

在FireFox(7+)和Chrome(14+)上,您可以将svg_element拉到顶部。这并没有给你完全z轴控制的自由,但它总比没有好;)

再次附加该元素。

var svg = doc.createElemNS('svg');
var circle = doc.createElemNS('circle');
var line = doc.createElemNS('line');

svg.appendChild(circle); // appends it
svg.appendChild(line);   // appends it over circle
svg.appendChild(circle); // redraws it over line now

我认为这会引发错误或其他事情。

  

appendChild ==替换自己==重绘

答案 3 :(得分:5)

未提及的另一个解决方案是将每个svg项/项集放入div中。您可以轻松更改div的z-index。

Fiddle: SVG elements cycles with z-index for containers

...按下按钮将该元素“推”到前面。 (vs重新绘制整个集合并将1个元素推到前面,但保持原始顺序与接受的解决方案一样)

拥有相对z指数会非常好......

如果它是来自jsfiddle的链接,那么stackOverflow是否要我放置代码?... ook

var orderArray=[0,1,2];
var divArray = document.querySelectorAll('.shape');
var buttonArray = document.querySelectorAll('.button');

for(var i=0;i<buttonArray.length;i++){
    buttonArray[i].onclick=function(){
        var localI = i;
        return function(){clickHandler(orderArray.indexOf(localI));};
    }();
}


function clickHandler(divIndex) {
     orderArray.push(orderArray.splice(divIndex, 1)[0]);
    orderDivs();
}

function orderDivs(){
    for(var i=0;i<orderArray.length;i++){
       divArray[orderArray[i]].style.zIndex=i;        
    }
}
svg {
    width: 100%;
    height: 100%;
    stroke: black;
    stroke-width:2px;
    pointer-events: all;
}
div{
    position:absolute;
}
div.button{
    top:55%;
    height:5%;
    width:15%;
    border-style: outset;
    cursor:pointer;
    text-align: center;
    background:rgb(175, 175, 234);
    
}
div.button:hover{
    border-style: inset;
    background:yellow;
    
}
div.button.first{
    left:0%;
}
div.button.second{
    left:20%;
}
div.button.third{
    left:40%;
}
<div class="shape">
    <svg>
    <circle cx="50" cy="50" r="40" fill="lime" />
    </svg>
</div>
<div class="shape">
    <svg>
        <rect x="4" y="20" width="200" height="50" fill="cyan" />
    </svg>
</div>
<div class="shape">
    <svg>
        <circle cx="70" cy="70" r="50" fill="fuchsia" />
    </svg>
</div>

<div class='button first'>lime</div>
<div class='button second'>cyan</div>
<div class='button third'>fuchsia</div>

答案 4 :(得分:4)

是的,顺序是指定哪个对象在另一个之前。要操纵顺序,您需要移动有关DOM的内容。在https://www.w3.org/TR/SVG/render.html#RenderingOrder

的SVG维基上有一个很好的例子

答案 5 :(得分:4)

如果您使用svg.js library,则可以使用“.front()”命令将任何元素移到顶部。

答案 6 :(得分:3)

SVG使用渲染的“画家模型”。在连续操作中将涂料应用于输出设备,使得每个操作在输出设备的某些区域上进行涂漆。当该区域与先前绘制的区域重叠时,新的涂料会部分或完全遮盖旧区域.- link to this

答案 7 :(得分:2)

在SVG中,要获得更大的Z索引,您应该在DOM树中向下移动元素。您可以使用jQuery执行此操作,选择SVG元素,将其删除并将其再次附加到您想要的位置:

$('g.element').remove().appendTo('svg');

答案 8 :(得分:1)

亚当布拉德利对萨姆的答案的评论正是关键所在。它只使用jQuery而不是CSS,但他说:

$('#grid').on('click','.save', function() {
    ...
    ...
});

然而,对于我的创建,我需要我的SVG路径在悬停时高于任何其他路径,但仍然低于我的SVG文本。所以这就是我想出的:

$('#thing-i-want-on-top').appendTo('#my-svg');

appendTo和insertBefore都会将你的元素移动到一个新的位置,允许你随意改变SVG元素的深度。