Как переместить дочерний элемент от одного родителя к другому с помощью jQuery

Я использую подключаемый модуль jQuery DataTables. Я хотел бы переместить поле поиска (.dataTables_filter) и количество записей для отображения раскрывающегося списка (.dataTables_length) из их родительского элемента (.dataTables_wrapper) в другой div на моей странице без потери какого-либо зарегистрированного поведения javascript. Например, в поле поиска есть функция, прикрепленная к событию keyup, и я хочу сохранить ее.

DOM выглядит так:

<body>
<div id="parent1">
  <div class="dataTables_wrapper" id="table1_wrapper">
    <div class="dataTables_length" id="table1_length">
      <select size="1" name="table1_length">
        <option value="10">10</option>
        <option value="25">25</option>
        <option value="50">50</option>
        <option value="100">100</option>
      </select>
    </div>
    <div class="dataTables_filter" id="table1_filter">
      <input type="text" class="search">
    </div>
    <table id="table1">
    ...
    </table>
  </div>
</div>
<div id="parent2">
  <ul>
    <li><a href="#">Link A</a></li>
    <li><a href="#">Link B</a></li>
    <li><a href="#">Link C</a></li>
  </ul>
</div>
</body>

Вот как я бы хотел, чтобы DOM выглядела после переезда:

<body>
<div id="parent1">
  <div class="dataTables_wrapper" id="table1_wrapper">
    <table id="table1">
    ...
    </table>
  </div>
</div>
<div id="parent2">
  <div class="dataTables_filter" id="table1_filter">
    <input type="text" class="search">
  </div>
  <div class="dataTables_length" id="table1_length">
    <select size="1" name="table1_length">
      <option value="10">10</option>
      <option value="25">25</option>
      <option value="50">50</option>
      <option value="100">100</option>
    </select>
  </div>
  <ul>
    <li><a href="#">Link A</a></li>
    <li><a href="#">Link B</a></li>
    <li><a href="#">Link C</a></li>
  </ul>
</div>
</body>

Я смотрел на функции .append (), .appendTo (), .prepend () и .prependTo (), но мне не повезло с ними на практике. Я также посмотрел на функции .parent () и .parents (), но, похоже, не могу написать работоспособное решение. Я также подумал об изменении CSS, чтобы элементы были абсолютно позиционированы, но, честно говоря, страница настроена с плавными элементами повсюду, и я действительно хочу, чтобы эти элементы перемещались в своих новых родительских элементах.

Любая помощь с этим очень ценится.


person Dom    schedule 08.04.2010    source источник
comment
Все перечисленные вами функции манипулирования DOM должны работать нормально. Добавление элемента DOM к другому родительскому элементу перемещает его в новую позицию, сохраняя все события нетронутыми. Что именно у вас не работает? Есть ошибка?   -  person Anurag    schedule 08.04.2010


Ответы (4)


$('#parent2').prepend($('#table1_length')).prepend($('#table1_filter'));

у вас не работает? Я думаю, это должно ...

person Alex Lawford    schedule 08.04.2010
comment
Это была проблема с наименованием. Мой пример выше работает нормально. Фактические идентификаторы полей содержали в себе несколько и _, и я не выбирал элемент, потому что идентификатор не совпадал. Спасибо. - person Dom; 08.04.2010

Поскольку ответ Jage полностью удаляет элемент, включая обработчики событий и данные, я добавляю простое решение, которое этого не делает, благодаря функции detach.

var element = $('#childNode').detach();
$('#parentNode').append(element);

Изменить:

В комментариях ниже Игорь Мухин предложил еще более короткую версию:

$("#childNode").detach().appendTo("#parentNode");

person eric.itzhak    schedule 18.10.2012
comment
это лучшее решение, потому что detach () + append () не клонирует элемент, а перемещает его в новое место. Таким образом, события и связанные с ними данные не потеряются - person Denes Papp; 17.01.2013
comment
это должно быть отмечено как ответ. - person Daniel; 29.01.2013
comment
Еще короче $("#childNode").detach().appendTo("#parentNode"); - person Igor Mukhin; 13.06.2013
comment
Я все время использую ответ Иимухина. Простой. чистый. - person jchwebdev; 12.11.2013
comment
За исключением того, что вам не нужно отсоединяться. Смотрите мой ответ ниже. - person JackArbiter; 04.12.2013
comment
@JackArbiter - detach был полезен для меня, потому что мне нужно временно удалить дочерние элементы из родителя для обработки, а затем вернуть их вместе с их исходным родителем (стиль CPS), поэтому, хотя это бесполезно в экземпляре вопроса (родительский для приемного родителя) это решило мою проблему;) - person Campbeln; 20.05.2014

Detach не требуется.

Ответ (по состоянию на 2013 год) прост:

$('#parentNode').append($('#childNode'));

Согласно http://api.jquery.com/append/

Вы также можете выбрать элемент на странице и вставить его в другой:

$ ('. контейнер'). append ($ ('h2'));

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

person JackArbiter    schedule 29.04.2013
comment
Я обнаружил, что отсоединение дает мне другое поведение в старых браузерах, таких как IE (и даже Edge). Например, Bootstraps DateTimePicker не работал бы, если бы родительский элемент был отсоединен и добавлен, однако простое использование append () для перемещения моих элементов оставило DateTimePicker счастливым. - person geekinit; 17.01.2019

Основываясь на полученных ответах, я решил сделать для этого быстрый плагин:

(function($){
    $.fn.moveTo = function(selector){
        return this.each(function(){
            var cl = $(this).clone();
            $(cl).appendTo(selector);
            $(this).remove();
        });
    };
})(jQuery);

Использование:

$('#nodeToMove').moveTo('#newParent');
person Jage    schedule 04.01.2012
comment
Этот метод клонирует элементы, а не перемещает их. в частности, если у вас есть хранилище в переменной $ ('# nodeToMove') до вызова moveTo, она больше не будет работать - person Roberto; 21.02.2013
comment
@Jage, почему бы не использовать синтаксис JQuery? $ ('# nodeToMove'). appendTo ('# newParent'); api.jquery.com/appendto - person Randall Flagg; 19.10.2015