Как поменять местами элементы DOM-дерева?

Рейтинг: 0Ответов: 2Опубликовано: 19.03.2023

Предположим, что у нас есть два узла DOM-дерева, такие,
что ни один из них не находится в поддереве у другого, например 3 и 9.

введите сюда описание изображения

Как в общем случае вполне поменять местами такие узлы DOM?

function swap(node1: Element, node2: Element) {
}

Ответы

▲ 1Принят

так как нужно лишь поменять местами, достаточно выполнить один 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>

▲ 0

Решение на основе симметричной пары ссылок:

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 (не оптимизирует случай с соседством).