Як перемістити елемент в інший елемент?


1688

Я хотів би перемістити один елемент DIV всередину іншого. Наприклад, я хочу перенести це (включаючи всіх дітей):

<div id="source">
...
</div>

в це:

<div id="destination">
...
</div>

щоб у мене було таке:

<div id="destination">
  <div id="source">
    ...
  </div>
</div>

21
Просто використовуйте $ (target_element) .append (to_be_inserted_element);
Мохаммед Аріб Сиддікі

2
Або: target.appendChild (джерело) з використанням простого javascript
luke

чи можемо ми досягти цього за допомогою CSS? це можливо?
RajKumar Samala

6
@RajKumarSamala CSS не може змінити структуру HTML, лише його представлення.
Марк Річман

Відповіді:


38

Ніколи не пробував звичайний JavaScript ... destination.appendChild(source);?

onclick = function(){ destination.appendChild(source); }
div{ margin: .1em; } 
#destination{ border: solid 1px red; }
#source {border: solid 1px gray; }
<!DOCTYPE html>
<html>

 <body>

  <div id="destination">
   ###
  </div>
  <div id="source">
   ***
  </div>

 </body>
</html>


* хтось встановив глобальну подію onclick демо-фрагмента за допомогою ключового слова varв його спробі покращити публікацію - але це неправильно!
Бекім Бакай

6
Дивно, як люди досі думають, що jQuery дорівнює JavaScript. У 2017 році вже немає потреби в jQuery.
nkkollaw

2
немає необхідності в jquery в 2017 році, але іноді це допомагає використовувати щось легше і подібне для завдань, які ви знову і знову робите в кожному проекті. Я використовую готівковий дім як простий спосіб слухати події document.ready, window.load по зручному для браузера способом. Простенька.
eballeste

1
Змінивши це на прийняту відповідь, тепер, коли настає 2020 рік :)
Марк Річман

1
Дивно, як люди досі думають, що jQuery дорівнює JavaScript. Насправді, у 2020 році більше не потрібно jQuery.
ii iml0sto1

1793

Ви можете скористатися appendToфункцією (яка додає до кінця елемента):

$("#source").appendTo("#destination");

Крім того, ви можете використовувати prependToфункцію (яка додає до початку елемента):

$("#source").prependTo("#destination");

Приклад:


23
Попередження про те, що це може не працювати належним чином у jQuery mobile, оскільки може натомість створити іншу копію елемента.
Йордан Рейтер

32
чи додатокСтворює копію чи фактично переміщує цілий div до місця призначення? (тому що якщо вона копіює, вона створювала б помилки під час виклику діви за ідентифікатором)

50
Ось чудова стаття про видалення, заміну
xhh

42
Зверніть увагу на документацію jQuery для appendTo повідомляє, що елемент переміщено: it will be moved into the target (not cloned) and a new set consisting of the inserted element is returned- api.jquery.com/appendto
John K

15
Ви його не рухаєте, просто додаєте. Нижче відповідь робить належний ПЕРЕМОГА.
Аарон

913

моє рішення:

ПЕРЕМОГА:

jQuery("#NodesToMove").detach().appendTo('#DestinationContainerNode')

КОПІЯ:

jQuery("#NodesToMove").appendTo('#DestinationContainerNode')

Зверніть увагу на використання .detach (). Під час копіювання будьте обережні, щоб не дублювати ідентифікатори.


86
Найкраща відповідь. Прийнята відповідь створює копію, не переміщує елемент, як запитання.
paulscode

97
Вибачте, але прийнята відповідь Ендрю Зайця правильна - відрив непотрібний. Спробуйте це в JSFiddle Pixic вище - якщо ви вилучите відокремлені виклики, він працює точно так само, тобто він робить переміщення, а не копію. Ось вилка з лише цією зміною: jsfiddle.net/D46y5 Як зафіксовано в API: api.jquery.com/appendTo : "Якщо вибраний таким чином елемент буде вставлено в одне місце в іншому місці DOM, він буде переміщений в ціль (не клонований) і повертається новий набір, що складається з вставленого елемента "
Іоанн - не номер

8
@ John-NotANumber має рацію - detach () тут не потрібен. Прийнята відповідь найкраща, вам просто потрібно фактично прочитати документацію належним чином.
ЛеонардШалліс

11
Документація Додаток також говорить: "Якщо є більше одного цільового елемента, проте, для кожної цілі після першого буде створено клоновані копії вставленого елемента, і цей новий набір (вихідний елемент плюс клони) повернеться." Тож у загальному випадку це рішення МОЖЕ також створювати копії!
Вінсент Пазеллер

чудово! Або ви можете скористатися цією точністю щодо того, куди рухатись$('#nodeToMove').insertAfter('#insertAfterThisElement');
Віктор Аугусто

108

Я щойно використовував:

$('#source').prependTo('#destination');

Якого я схопив звідси .


7
Ну, від'єднання корисно, коли ви хочете втриматись за елемент і знову вставити його згодом, але у вашому прикладі ви все одно вмикаєте його миттєво.
Тім Бют

1
Боюся, що я не дуже балакаю те, що ви отримуєте, чи можете ви надати зразок коду?
kjc26ster

1
Я маю на увазі, prependTo, від'єднує елемент з його початкового положення, вставляє його в нове. З іншого боку, функція від'єднання просто від'єднує вибраний елемент, і ви можете зберегти його у змінній, щоб потім вставити його в DOM. Вся справа в тому, що ваш виклик не потрібний. Видаліть його, і ви досягнете такого ж ефекту.
Тім Бют

1
Неймовірно, що правки повністю змінили цю відповідь до того, що через рік була додана ще одна відповідь (ідентична оригіналу) та отримано 800+ оновлень ...
hlscalon

96

Що з рішенням JavaScript ?

// Declare a fragment:
var fragment = document.createDocumentFragment();

// Append desired element to the fragment:
fragment.appendChild(document.getElementById('source'));

// Append fragment to desired element:
document.getElementById('destination').appendChild(fragment);

Перевір.


8
Чому використовувати createDocumentFragment замість просто document.getElementById ('призначення'). AppendChild (document.getElementById ('source'))?
Гунар Гесснер

6
@ GunarC.Gessner припускаючи, що вам потрібно змінити вихідний об'єкт перед тим, як додати його до об'єкта призначення, тоді найкращим підходом є використання фрагмента, який є уявним об’єктом і не є частиною дерева DOM, ви отримуєте кращу ефективність при зміні вихідний об'єкт, коли він був перенесений з його початкового місця (тепер він знаходиться всередині фрагмента), а не змінювати його на своєму початковому місці перед додаванням.
Алі Бассам

5
Хочу додати актуальність пропонування чистого рішення JavaScript. Не слід вважати, що jQuery завжди використовується
Олександр Фрадиані

1
Запитання: Додаючи дочірній вузол, чи втрачаємо ми додані події?
jimasun

1
Відповідь на моє власне запитання - це так, воно зберігає події, що додаються.
jimasun

95

Якщо там, divде ви хочете помістити ваш елемент, є вміст всередині, і ви хочете, щоб елемент відображався після основного вмісту:

  $("#destination").append($("#source"));

Якщо там, divде ви хочете помістити ваш елемент, є вміст всередині, і ви хочете показати елемент перед основним вмістом:

$("#destination").prepend($("#source"));

Якщо divелемент, куди ви хочете поставити, порожній, або ви хочете його повністю замінити :

$("#element").html('<div id="source">...</div>');

Якщо ви хочете дублювати елемент перед будь-яким із перерахованих вище:

$("#destination").append($("#source").clone());
// etc.

Мені здається, що все жирне шрифт трохи важко читати, але це найбільш інформативна відповідь, тому воно отримує мою оцінку.
Майкл Шепер

32

Ви можете використовувати:

Щоб вставити після,

jQuery("#source").insertAfter("#destination");

Щоб вставити всередину іншого елемента,

jQuery("#source").appendTo("#destination");

20

Якщо ви хочете швидкої демонстрації та більше детальних відомостей про переміщення елементів, спробуйте це посилання:

http://html-tuts.com/move-div-in-another-div-with-jquery


Ось короткий приклад:

Щоб переміститися НАД ЕЛЕМЕНТ:

$('.whatToMove').insertBefore('.whereToMove');

Щоб переміститися ПІСЛЯ елемента:

$('.whatToMove').insertAfter('.whereToMove');

Щоб переміститися всередині елемента, ВІД ВСІХ елементів всередині цього контейнера:

$('.whatToMove').prependTo('.whereToMove');

Щоб переміститися всередині елемента, ПІСЛЯ ВСІХ елементів всередині цього контейнера:

$('.whatToMove').appendTo('.whereToMove');

19

Ви можете використовувати наступний код для переміщення джерела до місця призначення

 jQuery("#source")
       .detach()
       .appendTo('#destination');

спробуйте працюючи кодек


11

Старе питання, але потрапив сюди, тому що мені потрібно переміщати вміст з одного контейнера в інший, включаючи всіх слухачів події .

jQuery не має способу це зробити, але стандартна DOM функція appendChild робить.

//assuming only one .source and one .target
$('.source').on('click',function(){console.log('I am clicked');});
$('.target')[0].appendChild($('.source')[0]);

Використання appendChild видаляє .source та розміщує його в цілі, включаючи його слухачів подій: https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild


6

Ви також можете спробувати:

$("#destination").html($("#source"))

Але це повністю замінить все, що у вас є #destination.


2
І перервати слухачів подій на переміщений елемент.
Ігор Помаранський

4

Я помітив величезну різницю пам’яті та продуктивність пам’яті між insertAfter& afterабо insertBefore& before.. Якщо у вас є безліч елементів DOM або вам потрібно використовувати after()або before()всередині MouseMove події , пам’ять браузера, ймовірно, збільшиться, і наступні операції будуть працювати дуже повільно.

Я щойно переживав це рішення - використовувати вместо цього before()insertBefore і замість insertAfter after().


Це звучить як проблема, що залежить від реалізації двигуна JavaScript. З якою версією браузера та двигуном JS ви бачите це?
Марк Річман

1
Я перебуваю на версії Chrome 36.0.1985.125 і використовую jQuery v1.11.1. Я пов'язую функцію на події mousemove, яка переміщує простий DIV вниз або вгору на елемент, над яким миша закінчилася. Тому ця подія та функція працює під час перетягування курсору. Витік пам'яті відбувається з після () та до (), якщо ви переміщуєте курсор на 30 сек +, і він зникає, якщо я просто використовую insertAfter & insertBefore замість цього.
спецназ

1
Я б відкрив помилку в Google на цьому.
Марк Річман

2

Ви можете використовувати чистий JavaScript, використовуючи appendChild()метод ...

Метод appendChild () додає вузол до останнього дочірнього вузла.

Порада: Якщо ви хочете створити новий абзац з текстом, не забудьте створити текст у вигляді текстового вузла, який ви додаєте до абзацу, а потім додайте абзац до документа.

Ви також можете використовувати цей метод для переміщення елемента з одного елемента в інший.

Порада: Використовуйте метод insertBefore (), щоб вставити новий дочірній вузол перед вказаним, існуючим, дочірнім вузлом.

Отже, ви можете зробити це, щоб виконати цю роботу. Це те, що я створив для вас, використовуючи appendChild(), запустіть і подивіться, як це працює для вашої справи:

function appendIt() {
  var source = document.getElementById("source");
  document.getElementById("destination").appendChild(source);
}
#source {
  color: white;
  background: green;
  padding: 4px 8px;
}

#destination {
  color: white;
  background: red;
  padding: 4px 8px;
}

button {
  margin-top: 20px;
}
<div id="source">
  <p>Source</p>
</div>

<div id="destination">
  <p>Destination</p>
</div>

<button onclick="appendIt()">Move Element</button>


0

Для повноти існує інший підхід wrap()або wrapAll()згадується в цій статті . Таким чином, питання ОП, можливо, може бути вирішене цим (тобто, якщо припустити, що <div id="destination" />це ще не існує, наступний підхід створить таку обгортку з нуля - ОП не було зрозуміло про те, чи вже така упаковка існує чи ні):

$("#source").wrap('<div id="destination" />')
// or
$(".source").wrapAll('<div id="destination" />')

Це звучить багатообіцяюче. Однак, коли я намагався зробити $("[id^=row]").wrapAll("<fieldset></fieldset>")на декількох вкладених структурах так:

<div id="row1">
    <label>Name</label>
    <input ...>
</div>

Це правильно обертає ті <div>...</div>і <input>...</input>АЛЕ ІНАКШЕ пропускає <label>...</label>. Тому я $("row1").append("#a_predefined_fieldset")замість цього скористався явним . Отже, YMMV.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.