Как изменить порядок элементов svg

Я работаю с элементом 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>

Это дает мне это Как изменить порядок элементов svg

Есть ли лучший способ сделать это?

Почему за это проголосовали?

smpa01 07.04.2022 02:56
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

append(child) сами по себе движется DOM Nodes. Таким образом, ваш код может быть упрощен.

Но для более сложного SVG вы, вероятно, захотите использовать позиции менять DOM, потому что между ними могут быть другие элементы, на которые вы не хотите воздействовать.

  • Удерживайте клавишу CTRL, чтобы увидеть, что происходит с append
  • Нажмите, чтобы увидеть версию обмена,
    вопрос обработки массива и замены первого элемента последним.
  • Примечание: append не был доступен в Internet Explorer, поэтому вы видите большинство сообщений, использующих appendChild.
    В современных браузерах гораздо больше возможностей DOM: replaceWithafter , 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>

Другие вопросы по теме