Я работаю с элементом 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 Nodes. Таким образом, ваш код может быть упрощен.
Но для более сложного SVG вы, вероятно, захотите использовать позиции менять DOM, потому что между ними могут быть другие элементы, на которые вы не хотите воздействовать.
append
append
не был доступен в Internet Explorer, поэтому вы видите большинство сообщений, использующих appendChild
.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>
Почему за это проголосовали?