Làm thế nào để di chuyển một yếu tố thành một yếu tố khác?


1689

Tôi muốn di chuyển một yếu tố DIV bên trong một yếu tố khác. Ví dụ: tôi muốn di chuyển cái này (bao gồm tất cả trẻ em):

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

vào đây:

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

để tôi có cái này:

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

21
Chỉ cần sử dụng $ (target_element) .append (to_be_inserted_element);
Mohammad Areeb Siddiqui

2
Hoặc: Destination.appendChild (nguồn) bằng cách sử dụng javascript đơn giản
luke

chúng ta có thể đạt được điều này bằng CSS không? điều đó có thể không ?
RajKumar Samala

6
@RajKumarSamala CSS không thể thay đổi cấu trúc của HTML, chỉ có phần trình bày của nó.
Đánh dấu Richman

Câu trả lời:


39

Bạn đã bao giờ thử JavaScript đơn giản chưa ... 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>


* ai đó đã bắt đầu sự kiện toàn cầu onclick của đoạn giới thiệu với từ khóa vartrong nỗ lực của mình để cải thiện bài đăng - nhưng điều đó đã sai!
Bekim Bacaj

6
Thật đáng kinh ngạc khi mọi người vẫn nghĩ jQuery bằng JavaScript. Không cần jQuery nữa vào năm 2017, thật đấy.
nkkollaw

2
không cần jquery trong năm 2017 nhưng đôi khi nó giúp sử dụng một cái gì đó nhẹ hơn và tương tự cho các nhiệm vụ bạn thấy mình làm đi làm lại nhiều lần trong mỗi dự án. tôi sử dụng cash-dom như một cách dễ dàng để nghe tài liệu. yet, window.load các sự kiện theo cách thân thiện với nhiều trình duyệt. dễ như ăn bánh.
eballeste

1
Thay đổi câu trả lời này thành câu trả lời được chấp nhận, bây giờ là năm 2020 :)
Mark Richman

1
Thật đáng kinh ngạc khi mọi người vẫn nghĩ jQuery bằng JavaScript. Không cần jQuery nữa vào năm 2020, thực sự.
ii iml0sto1

1794

Bạn có thể muốn sử dụng appendTohàm (thêm vào cuối phần tử):

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

Ngoài ra, bạn có thể sử dụng prependTohàm (thêm vào phần đầu của phần tử):

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

Thí dụ:


23
Một cảnh báo rằng điều này có thể không hoạt động chính xác trong jQuery mobile, vì nó có thể tạo một bản sao khác của phần tử thay thế.
Jordan Reiter

32
appen Để tạo một bản sao hoặc thực sự di chuyển toàn bộ div đến đích? (bởi vì nếu nó sao chép, nó sẽ tạo ra erros khi gọi div bằng id)

50
Đây là một bài viết tuyệt vời về Loại bỏ, thay thế và di chuyển các yếu tố trong jQuery: elated.com/articles/jquery-removing-replaces-moving-elements
xhh

42
Lưu ý tài liệu jQuery cho append Để nói rằng phần tử được di chuyển: 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
Bạn không di chuyển nó, chỉ cần thêm. Dưới đây câu trả lời không di chuyển đúng.
Aaron

913

giải pháp của tôi:

DI CHUYỂN:

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

SAO CHÉP:

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

Lưu ý cách sử dụng .detach (). Khi sao chép, hãy cẩn thận rằng bạn không sao chép ID.


86
Câu trả lời tốt nhất. Câu trả lời được chấp nhận sẽ tạo ra một bản sao, không di chuyển phần tử như câu hỏi yêu cầu.
paulscode

97
Xin lỗi, nhưng câu trả lời được chấp nhận của Andrew Hare là chính xác - việc tách ra là không cần thiết. Hãy thử nó trong JSFiddle của Pixic ở trên - nếu bạn loại bỏ các lệnh gọi thì nó hoạt động giống hệt nhau, tức là nó di chuyển, KHÔNG phải là bản sao. Đây là một ngã ba chỉ với một thay đổi: jsfiddle.net/D46y5 Như được ghi trong API: api.jquery.com/appendTo : "Nếu một phần tử được chọn theo cách này được chèn vào một vị trí khác trong DOM, nó sẽ được di chuyển vào mục tiêu (không được nhân bản) và một bộ mới bao gồm phần tử được chèn được trả về "
John - Không phải là số

8
@ John-NotANumber là đúng - tách ra () không cần thiết ở đây. Câu trả lời được chấp nhận là tốt nhất, bạn chỉ cần thực sự đọc tài liệu đúng cách.
LeonardChallis

11
Tài liệu appendTo cũng cho biết: "Tuy nhiên, nếu có nhiều hơn một phần tử đích, các bản sao được sao chép của phần tử được chèn sẽ được tạo cho mỗi mục tiêu sau phần đầu tiên và bộ mới đó (phần tử gốc cộng với bản sao) được trả về.". Vì vậy, trong trường hợp chung, giải pháp này cũng CÓ THỂ tạo bản sao!
Vincent Pazeller 16/2/2015

tuyệt quá! Hoặc bạn có thể sử dụng điều này để cụ thể hơn về nơi di chuyển$('#nodeToMove').insertAfter('#insertAfterThisElement');
Victor Augusto

108

Tôi chỉ sử dụng:

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

Mà tôi lấy từ đây .


7
Chà, tách ra rất hữu ích khi bạn muốn giữ nguyên tố đó và đặt lại nó sau này, nhưng trong ví dụ của bạn, bạn sẽ đặt lại nó ngay lập tức.
Tim Büthe

1
Tôi sợ rằng tôi không hoàn toàn mò mẫm những gì bạn đang nhận được, bạn có thể cung cấp mã mẫu không?
kjc26ster

1
Ý tôi là, preendTo, tách phần tử khỏi vị trí ban đầu của nó và chèn nó vào vị trí mới. Mặt khác, chức năng tách ra chỉ tách phần tử được chọn và bạn có thể lưu nó trong một biến để chèn nó vào DOM vào một thời điểm sau. Điều này là, cuộc gọi tách ra của bạn là không cần thiết. Loại bỏ nó và bạn sẽ đạt được hiệu quả tương tự.
Tim Büthe

1
Thật đáng kinh ngạc khi các chỉnh sửa đã thay đổi hoàn toàn câu trả lời này đến mức một câu trả lời khác đã được thêm vào một năm sau đó (giống hệt với bản gốc) và có hơn 800 lượt
upvote

96

Điều gì về một giải pháp 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);

Kiểm tra nó ra.


8
Tại sao sử dụng createDocumentFragment thay vì chỉ đơn giản là document.getEuityById ('Destination'). AppendChild (document.getEuityById ('source'))?
Gunar Gessner

6
@ GunarC.Gessner giả sử bạn cần sửa đổi đối tượng nguồn trước khi thêm nó vào đối tượng đích, thì cách tiếp cận tốt nhất là sử dụng đoạn là đối tượng tưởng tượng và không phải là một phần của cây DOM, bạn sẽ có hiệu suất tốt hơn khi sửa đổi đối tượng nguồn khi nó đã được chuyển từ vị trí ban đầu của nó (bây giờ nó nằm trong đoạn) thay vì sửa đổi nó ở vị trí ban đầu trước khi nối nó.
Ali Bassam

5
Tôi muốn thêm vào sự liên quan của việc cung cấp một giải pháp thuần túy JavaScript. Không nên giả sử jQuery luôn được sử dụng
Alexander Fradiani

1
Câu hỏi: Khi nối thêm nút con, chúng ta có bị mất các sự kiện đính kèm không?
jimasun

1
Câu trả lời cho câu hỏi của riêng tôi là có, nó không giữ các sự kiện kèm theo.
jimasun

95

Nếu divnơi bạn muốn đặt phần tử của bạn có nội dung bên trong và bạn muốn phần tử hiển thị sau nội dung chính:

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

Nếu divnơi bạn muốn đặt phần tử của bạn có nội dung bên trong và bạn muốn hiển thị phần tử đó trước nội dung chính:

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

Nếu divnơi bạn muốn đặt phần tử của bạn trống hoặc bạn muốn thay thế hoàn toàn:

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

Nếu bạn muốn sao chép một phần tử trước bất kỳ phần nào ở trên:

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

Tôi thấy tất cả các chữ in đậm hơi khó đọc, nhưng đây là câu trả lời nhiều thông tin nhất, vì vậy nó nhận được sự ủng hộ của tôi.
Michael Scheper

32

Bạn có thể dùng:

Để chèn sau,

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

Để chèn bên trong một phần tử khác,

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

20

Nếu bạn muốn có bản demo nhanh và biết thêm chi tiết về cách bạn di chuyển các yếu tố, hãy thử liên kết này:

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


Đây là một ví dụ ngắn:

Để di chuyển TRÊN một phần tử:

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

Để di chuyển SAU một yếu tố:

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

Để di chuyển bên trong một phần tử, TRÊN TẤT CẢ các phần tử bên trong thùng chứa đó:

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

Để di chuyển bên trong một phần tử, SAU TẤT CẢ các phần tử bên trong thùng chứa đó:

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

19

Bạn có thể sử dụng mã sau để di chuyển nguồn đến đích

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

thử làm việc với codepen


11

Câu hỏi cũ nhưng có ở đây vì tôi cần chuyển nội dung từ thùng này sang thùng khác bao gồm tất cả những người nghe sự kiện .

jQuery không có cách nào để làm điều đó nhưng hàm DOM tiêu chuẩn appendChild thì có.

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

Việc sử dụng appendChild sẽ loại bỏ .source và đặt nó vào mục tiêu, bao gồm cả trình lắng nghe sự kiện: https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild


6

Bạn cũng có thể thử:

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

Nhưng điều này sẽ hoàn toàn ghi đè lên bất cứ điều gì bạn có #destination.


2
Và phá vỡ người nghe sự kiện trên các yếu tố di chuyển.
Igor Pomaranskiy

4

Tôi nhận thấy sự rò rỉ bộ nhớ lớn và sự khác biệt hiệu năng giữa insertAfter& afterhoặc insertBefore& before.. Nếu bạn có hàng tấn phần tử DOM hoặc bạn cần sử dụng after()hoặc before()bên trong một sự kiện MouseMove , bộ nhớ trình duyệt có thể sẽ tăng và các hoạt động tiếp theo sẽ chạy rất chậm.

Giải pháp tôi vừa trải nghiệm là sử dụng inserB Before thay thế before()và insertAfter thay thế after().


Điều này nghe có vẻ như là một vấn đề phụ thuộc vào việc triển khai công cụ JavaScript. Phiên bản trình duyệt và công cụ JS nào bạn thấy điều này với?
Mark Richman

1
Tôi đang dùng Chrome phiên bản 36.0.1985.125 và đang sử dụng jQuery v1.11.1. Tôi liên kết một chức năng trong sự kiện mousemove, nó di chuyển một DIV đơn giản xuống hoặc lên phần tử mà chuột kết thúc. Do đó, sự kiện & chức năng này chạy trong khi bạn kéo con trỏ. Rò rỉ bộ nhớ xảy ra với after () và before (), nếu bạn di chuyển con trỏ trong 30 giây + và nó sẽ biến mất nếu tôi chỉ sử dụng insertAfter & insertB Before thay thế.
spetsnaz

1
Tôi sẽ mở một lỗi với Google trên đó.
Mark Richman

2

Bạn có thể sử dụng JavaScript thuần túy, sử dụng appendChild()phương thức ...

Phương thức appendChild () nối thêm một nút làm con cuối cùng của một nút.

Mẹo: Nếu bạn muốn tạo một đoạn mới, bằng văn bản, hãy nhớ tạo văn bản dưới dạng nút Văn bản mà bạn nối vào đoạn đó, sau đó nối đoạn đó vào tài liệu.

Bạn cũng có thể sử dụng phương pháp này để di chuyển một yếu tố từ yếu tố này sang yếu tố khác.

Mẹo: Sử dụng phương thức insertB Before () để chèn một nút con mới trước một nút con được chỉ định, hiện có.

Vì vậy, bạn có thể làm điều đó để thực hiện công việc, đây là những gì tôi đã tạo cho bạn, sử dụng appendChild(), chạy và xem cách nó hoạt động cho trường hợp của bạn:

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

Để hoàn thiện, có một cách tiếp cận khác wrap()hoặc wrapAll()được đề cập trong bài viết này . Vì vậy, câu hỏi của OP có thể được giải quyết bằng cách này (nghĩa là giả sử <div id="destination" />chưa tồn tại, cách tiếp cận sau đây sẽ tạo ra một trình bao bọc như vậy từ đầu - OP không rõ về việc trình bao bọc đã tồn tại hay chưa):

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

Nghe có vẻ đầy hứa hẹn. Tuy nhiên, khi tôi cố gắng thực hiện $("[id^=row]").wrapAll("<fieldset></fieldset>")trên nhiều cấu trúc lồng nhau như thế này:

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

Nó kết thúc chính xác những điều đó <div>...</div><input>...</input>NHƯNG MỘT SỐ CÂU CHUYỆN RA KHỎI <label>...</label>. Vì vậy, tôi đã kết thúc sử dụng rõ ràng $("row1").append("#a_predefined_fieldset")thay thế. Vì vậy, YMMV.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.