Вопрос по jquery, javascript, dom – Поменяйте местами 2 HTML-элемента и сохраните на них прослушиватели событий

22

Есть похожие вопросы, но все ответы для обмена HTML-элементов только для содержимого внутри.

Мне нужно поменять местами два div с большим количеством контента (таблицы, блоки выбора, входы и т. Д.) Со слушателями событий на элементах и т. Д., Не разрушая все это.

У меня есть доступ к JQuery 1.5. Так что ответы с ним в порядке.

Ваш Ответ

6   ответов
1

parentNodes и nextSibling одного, вы можете поменять два элемента с их потомками без каких-либо временных заполнителей.

Если второй элемент является единственным потомком или последним потомком его родителя, его замена (правильно) добавляется к родителю.

function swap(a, b){
    var p1= a.parentNode, p2= b.parentNode, sib= b.nextSibling;
    if(sib=== a) sib= sib.nextSibling;
    p1.replaceChild(b, a);
    if(sib) p2.insertBefore(a, sib);
    else p2.appendChild(a);
    return true;
}
0

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

function swapElements(el1, el2) {
    var p2 = el2.parentNode, n2 = el2.nextSibling
    if (n2 === el1) return p2.insertBefore(el1, el2)
    el1.parentNode.insertBefore(el2, el1);
    p2.insertBefore(el1, n2);
}
0

как ваши события связаны с элементами, которые вы меняете. Если вы используете jQuery, тоэтот Ответ - все, что тебе нужно, правда.

Главное неdelete или жеremoveChildnode элементы, и просто скопируйте и вставьте HTML в другом месте. При этом некоторые браузеры очищают все ресурсы (включая обработчики событий), поэтому связанные события будут потеряны. Хотя IE печально известен утечкой памяти, когда речь идет о динамически связанных событиях. Трудно предсказать, как будут вести себя различные браузеры.

По сути, я бы сказал: меняйте элементы по своему усмотрению, за исключением копирования / вставки HTML-строк, и связывайте свои события с помощью jQuery..live() метод. Поскольку я не думаю, что 1.5 имеет.on метод

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededswap elements in any way you like, except for copy/paste HTML stringsError: User Rate Limit Exceeded
8

резагрузки элемента ...

function swapElements(obj1, obj2) {
    obj2.nextSibling === obj1
    ? obj1.parentNode.insertBefore(obj2, obj1.nextSibling)
    : obj1.parentNode.insertBefore(obj2, obj1); 
}

Примечание: если в obj1 есть встроенное видео, такое как YouTube, оно не будет перезагружаться при замене. Это просто положение элементов, которые изменились.

Error: User Rate Limit Exceededobj2Error: User Rate Limit Exceededobj1Error: User Rate Limit Exceededobj1Error: User Rate Limit Exceededobj2Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededthis jsFiddleError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
47

не теряя обработчики событий и не нарушая ссылки DOM, вы можете просто переместить их в DOM. Ключ НЕ в том, чтобы изменить innerHTML, потому что он воссоздает новые узлы DOM с нуля, и все предыдущие обработчики событий в этих объектах DOM теряются.

Но если вы просто переместите элементы DOM на новое место в DOM, все события останутся подключенными, потому что элементы DOM переопределяются без изменения самих элементов DOM.

Вот быстрая функция, которая поменяла бы два элемента в DOM. Он должен работать с любыми двумя элементами, если один не является потомком другого:

function swapElements(obj1, obj2) {
    // create marker element and insert it where obj1 is
    var temp = document.createElement("div");
    obj1.parentNode.insertBefore(temp, obj1);

    // move obj1 to right before obj2
    obj2.parentNode.insertBefore(obj1, obj2);

    // move obj2 to right before where obj1 used to be
    temp.parentNode.insertBefore(obj2, temp);

    // remove temporary marker node
    temp.parentNode.removeChild(temp);
}

Вы можете увидеть это работает здесь:http://jsfiddle.net/jfriend00/NThjN/

А вот версия, которая работает без вставленного временного элемента:

function swapElements(obj1, obj2) {
    // save the location of obj2
    var parent2 = obj2.parentNode;
    var next2 = obj2.nextSibling;
    // special case for obj1 is the next sibling of obj2
    if (next2 === obj1) {
        // just put obj1 before obj2
        parent2.insertBefore(obj1, obj2);
    } else {
        // insert obj2 right before obj1
        obj1.parentNode.insertBefore(obj2, obj1);

        // now insert obj1 where obj2 was
        if (next2) {
            // if there was an element after obj2, then insert obj1 right before that
            parent2.insertBefore(obj1, next2);
        } else {
            // otherwise, just append as last child
            parent2.appendChild(obj1);
        }
    }
}

Рабочая демонстрация:http://jsfiddle.net/jfriend00/oq92jqrb/

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceedednextSiblingError: User Rate Limit Exceedednext2Error: User Rate Limit ExceedednextSiblingError: User Rate Limit ExceedednextElementSiblingError: User Rate Limit ExceededalwaysError: User Rate Limit ExceededifError: User Rate Limit Exceededjsfiddle.net/8uyptyv0
0

  $('#el_to_move').appendTo('#target_parent_el');

Вот и все. JQuery будет вырезать / вставить его на новое место.

Это также может быть полезно:

https://api.jquery.com/detach/

Похожие вопросы