Как поменять местами элементы DOM-дерева?
Предположим, что у нас есть два узла DOM-дерева, такие,
что ни один из них не находится в поддереве у другого, например 3 и 9.
Как в общем случае вполне поменять местами такие узлы DOM?
function swap(node1: Element, node2: Element) {
}
Ответы (2 шт):
так как нужно лишь поменять местами, достаточно выполнить один replaceChild, который возвращает заменяемый узел и вставить этот узел в место, где был первый.
Для правильной вставки можно использовать insertBefore. Чтобы найти узел перед которым надо вставить можно воспользоваться свойством .nextElementSibling
В случае, когда узлы идут друг за другом, достаточно просто воспользоваться insertBefore на этих узлах.
Пример:
function swap(node1, node2) {
var node1Next = node1.nextElementSibling;
if (node1Next == node2) {
node1.parentNode.insertBefore(node2, node1);
return;
}
node1.parentNode.insertBefore(node2.parentNode.replaceChild(node1, node2), node1Next);
}
swap(document.querySelector('.wrap1'), document.querySelector('.wrap2'));
<div class="wrap1">wrap1</div>
<div class="wrap2">wrap2</div>
<div class="">skip1</div>
<div class="">skip2</div>
<div class="">skip3</div>
<div class="wrap3">wrap3</div>
<div class="wrap4">wrap4</div>
Решение на основе симметричной пары ссылок:
function swap(node1, node2) {
const parent1 = node1.parentNode
const parent2 = node2.parentNode
const nextNode1 = node1.nextSibling
const nextNode2 = node2.nextSibling
parent1.insertBefore(node2, nextNode1)
parent2.insertBefore(node1, nextNode2)
}
const node1 = document.querySelector('.wrap1');
const node2 = document.querySelector('.wrap2');
swap(node1, node2);
<div class="wrap1">wrap1</div>
<div class="wrap2">wrap2</div>
<div class="">skip1</div>
<div class="">skip2</div>
<div class="">skip3</div>
<div class="wrap3">wrap3</div>
<div class="wrap4">wrap4</div>
Немного хуже решения Grundy (не оптимизирует случай с соседством).
