Перемещение элемента JavaScript в DOM

99

Скажем, у меня есть три <div>элемента на странице. Как я могу поменять местами первую и третью <div>? jQuery в порядке.

ядро
источник

Ответы:

111

Тривиально с jQuery

$('#div1').insertAfter('#div3');
$('#div3').insertBefore('#div2');

Если вы хотите делать это неоднократно, вам нужно будет использовать разные селекторы, поскольку блоки div сохранят свои идентификаторы при перемещении.

$(function() {
    setInterval( function() {
        $('div:first').insertAfter($('div').eq(2));
        $('div').eq(1).insertBefore('div:first');
    }, 3000 );
});
tvanfosson
источник
1
@Ionut - дело в том, что это зависит от взаимного расположения элементов. Как только вы измените порядок, вы больше не сможете найти первый и третий по их идентификаторам, и вам нужно будет найти другой способ. Мой ответ был предназначен только для того, чтобы проиллюстрировать функциональность методов для выполнения запрошенной задачи, а не быть исчерпывающим решением для замены первого и третьего div в наборе произвольное количество раз.
tvanfosson 01
Привет, ребята, быстрый вопрос: есть ли простой способ вернуться к исходному состоянию Dom после выполнения вышеуказанной функции jquery?
Викита
@Vikita - да, сохраните исходный HTML и восстановите его. Возможно, вам придется повторно применить любые обработчики, если они были применены напрямую, а не делегированы вышестоящему элементу. Например,var html = $('#container').html(); ...; $('#container').html(html);
tvanfosson 07
172

Для такой тривиальной задачи нет необходимости использовать библиотеку:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[2].parentNode.insertBefore(divs[2], divs[0]); // order: third, first, second
divs[2].parentNode.insertBefore(divs[2], divs[1]); // order: third, second, first

При этом учитывается тот факт, что getElementsByTagNameвозвращается активный NodeList, который автоматически обновляется, чтобы отразить порядок элементов в DOM по мере того, как ими манипулируют.

Вы также можете использовать:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[0].parentNode.appendChild(divs[0]);           // order: second, third, first
divs[1].parentNode.insertBefore(divs[0], divs[1]); // order: third, second, first

и есть различные другие возможные перестановки, если вы хотите поэкспериментировать:

divs[0].parentNode.appendChild(divs[0].parentNode.replaceChild(divs[2], divs[0]));

например :-)

НикФитц
источник
15
Верно, но трудно поспорить с элегантностью и удобочитаемостью, которые предоставляет что-то вроде jQuery, не говоря уже о расширенных возможностях из коробки.
Безумный Джо Маллой,
13
Да, но кто только это делает?
tvanfosson 01
1
... или на странице всего 3 блока
Райан Флоренс,
38
@everybody: исходный вопрос заключался в том, как поменять местами третий и первый div на странице с тремя div. Это был вопрос, на который я ответил. Если бы у OP был более сложный вопрос, они должны были бы его задать, и они бы получили более сложный ответ ;-)
NickFitz 02
27
Если кто-то ищет это в 2014 году, рассмотрите этот ответ. Тогда jQuery БЫЛ полезен, но теперь он уже не так полезен, потому что браузеры стандартизированы, поэтому не нужно добавлять библиотеку 80 КБ только для выполнения такой простой задачи. Кроме того, вы не узнаете, что такое DOM на самом деле, пока не попробуете его без jQuery :)
gustavohenke
31

.до и после

Используйте современный ванильный JS! Намного лучше / чище, чем раньше. Нет необходимости ссылаться на родителя.

const div1 = document.getElementById("div1");
const div2 = document.getElementById("div2");
const div3 = document.getElementById("div3");

div2.after(div1);
div2.before(div3);

Поддержка браузеров - 94,23% в мире по состоянию на июль 2020 г.

Гибольт
источник
Пока нет поддержки Internet Explorer.
Justnorris
11
Вам не нужно писать менее удобный в сопровождении код для поддержки людей, использующих старые браузеры или не соответствующие стандартам. Если вы не работаете на предприятии, немногие пользователи пропустят его
Гиболт
Другие методы работают так же хорошо с точки зрения ремонтопригодности, особенно при обертке красивой чистой функции. Я полностью за то, чтобы писать современный код, но это передний край. Приятно знать, что нас ждет в будущем, но как бы мне ни не нравилось все, что связано с IE, важно знать, как повлияют ваши решения. В данном случае - неработающее веб-приложение в любом браузере IE. Если ты не против - отлично! Я добавил комментарий, чтобы проинформировать кого-либо об этом в
гугле
1
Итак, 27% пользователей - это несколько пользователей ? Речь идет о миллионах!
SandRock
5
Через год эта цифра приблизится к 10%. В основном это корпоративные, государственные и старые мобильные устройства. Обычно это означает неличные устройства или менее технически подкованные пользователи. Ответы должны быть перспективными, чтобы мы не застряли в разработке в 2009 году.
Гиболт
11
jQuery.fn.swap = function(b){ 
    b = jQuery(b)[0]; 
    var a = this[0]; 
    var t = a.parentNode.insertBefore(document.createTextNode(''), a); 
    b.parentNode.insertBefore(a, b); 
    t.parentNode.insertBefore(b, t); 
    t.parentNode.removeChild(t); 
    return this; 
};

и используйте это так:

$('#div1').swap('#div2');

если вы не хотите использовать jQuery, вы можете легко адаптировать эту функцию.

Дарин Димитров
источник
5
var swap = function () {
    var divs = document.getElementsByTagName('div');
    var div1 = divs[0];
    var div2 = divs[1];
    var div3 = divs[2];

    div3.parentNode.insertBefore(div1, div3);
    div1.parentNode.insertBefore(div3, div2);
};

Эта функция может показаться странной, но для правильной работы она сильно зависит от стандартов. Фактически, может показаться, что он работает лучше, чем версия jQuery, опубликованная tvanfosson, которая, кажется, выполняет подкачку только дважды.

На какие особенности стандартов он опирается?

insertBefore Вставляет узел newChild перед существующим дочерним узлом refChild. Если refChild имеет значение null, вставьте newChild в конец списка дочерних элементов. Если newChild является объектом DocumentFragment, все его дочерние элементы вставляются в том же порядке перед refChild. Если newChild уже есть в дереве, сначала он удаляется.

Ионуй Г. Стан
источник
0

Подход Jquery, упомянутый вверху, будет работать. Вы также можете использовать JQuery и CSS. Скажите, например, в Div one вы применили class1 и div2, вы применили класс class2 (скажем, например, каждый класс css предоставляет определенную позицию в браузере), теперь вы можете поменять классы, используя jquery или javascript (который изменит позицию)

Раджат
источник
0

Извините за то, что натолкнулся на эту тему. Я наткнулся на проблему "подкачки DOM-элементов" и немного поигрался

Результатом является "родное" jQuery "решение", которое кажется действительно красивым (к сожалению, я не знаю, что происходит внутри jQuery при этом)

Код:

$('#element1').insertAfter($('#element2'));

В документации jQuery сказано, что элемент insertAfter() перемещается, а не клонируется.

буря
источник