如何反转svg元素的顺序

How to reverse the order of svg elements

我正在使用下面的 svg 元素

<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>

我想用javascript颠倒这些圆圈的顺序,我目前正在这样做

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>

它给了我这个

有更好的方法吗?

append(child) 本身 移动 DOM 个节点。这样你的代码就可以简化了。

但是对于更复杂的 SVG,您可能希望 swap DOM 位置,因为中间可能有您不想影响的其他元素。

  • 按住 CTRL 键查看 append
  • 会发生什么
  • 点击查看对换版本,
    处理数组并将第一个元素与最后一个元素交换的问题。
  • 注意:append 在 Internet Explorer 中不可用,这就是为什么您看到大多数帖子使用 appendChild
    现代浏览器加载了更多 DOM 好东西:replaceWith after , before

<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>