简体   繁体   中英

How to reverse the order of svg elements

I am working with a svg element which is following

 <svg class="layer1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150"> <rect class="bg" id="bg" width="150" height="150" fill="#e6e6e6"></rect> <circle class="circ0" id="circ0" cx="75" cy="75" r="72" fill="none" stroke="blue" stroke-linecap="round" stroke-linejoin="round"></circle> <circle class="circ1" id="circ1" cx="75" cy="75" r="69" fill="none" stroke="green" stroke-linecap="round" stroke-linejoin="round"></circle> <circle class="circ2" id="circ2" cx="75" cy="75" r="66" fill="none" stroke="red" stroke-linecap="round" stroke-linejoin="round"></circle> <script href="index.js"></script> </svg>

I want to reverse the order of these circles with javascript, which I am currently doing by this way

 const svg = document.querySelector("svg"); var x = document.querySelectorAll("[class^='circ']"); var bucket = []; x.forEach((a, i) => { bucket.push(a) }); bucket.reverse(); x.forEach( (a, i) => a.parentNode.removeChild(a) ); bucket.forEach( (a, i) => { a.setAttribute("class", 'circ' + [i]); a.setAttribute("id", "circ" + [i]); svg.appendChild(a); } )
 <svg class="layer1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150"> <rect class="bg" id="bg" width="150" height="150" fill="#e6e6e6"></rect> <circle class="circ0" id="circ0" cx="75" cy="75" r="72" fill="none" stroke="blue" stroke-linecap="round" stroke-linejoin="round"></circle> <circle class="circ1" id="circ1" cx="75" cy="75" r="69" fill="none" stroke="green" stroke-linecap="round" stroke-linejoin="round"></circle> <circle class="circ2" id="circ2" cx="75" cy="75" r="66" fill="none" stroke="red" stroke-linecap="round" stroke-linejoin="round"></circle> <script href="index.js"></script> </svg>

It gives me this折断

Is there a better way of doing this?

append(child) by itself moves DOM Nodes. So your code can be simplified.

But for complexer SVG you probably want to swap DOM positions, because there could be other Elements in between you don't want to affect.

  • Hold CTRL key to see what happens with append
  • Click to see the swapping version,
    a matter of processing an Array and swapping the first with the last element.
  • Note: append was not available in Inte.net Explorer, that is why you see most posts using appendChild .
    Modern browsers have loads more DOM goodies: replaceWith after , before etc.

 <svg viewBox="0 0 10 10" style="height:200px"> <style> text { font-size: 2px } [y="3"]{ fill:yellow }.first { stroke: black; stroke-width: 0.5 } </style> <rect class="bg" id="bg" width="10" height="10" fill="grey"></rect> <circle class="first" id="c0" cx="2" cy="5" r="2" fill="red" /> <text x="0" y="3">R</text> <circle class="second" id="c1" cx="4" cy="5" r="3" fill="green" /> <text x="1" y="3">G</text> <circle class="last" id="c2" cx="6" cy="5" r="4" fill="blue" /> <text x="2" y="3">B</text> <text x="1" y="6">Click Me.</text> </svg> <script> let svg = document;querySelector("svg"). function append() { [...svg.querySelectorAll("circle")].reverse(),forEach((c. i) => { c.parentNode;append(c). c,setAttribute("class". c;id = 'c' + i); }), } function swap() { function swapElements(e1, e2) { let {id,previousSibling:className:{baseVal;c2}} = e2. e1;after(e2). // put e2 after e1 e2.id = e1;id. e2,setAttribute("class". e1;getAttribute("class")). previousSibling;after(e1). // put e1 after where e2 WAS e1;id = id. e1,setAttribute("class"; c2). } let circles = [...svg;querySelectorAll("circle")]. while (circles.length) { let c1 = circles;shift(). if (circles,length) swapElements(c1. circles.pop()) } } svg.onclick = (e) => (e;ctrlKey && append()) || swap(); </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM