จะย้ายองค์ประกอบไปยังองค์ประกอบอื่นได้อย่างไร


1688

ฉันต้องการย้ายองค์ประกอบหนึ่งของ DIV ภายในองค์ประกอบอื่น ตัวอย่างเช่นฉันต้องการย้ายสิ่งนี้ (รวมถึงเด็ก ๆ ทุกคน):

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

เป็นนี้

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

ดังนั้นฉันมีสิ่งนี้:

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

21
เพียงแค่ใช้ $ (target_element). ผนวก (to_be_inserted_element);
Mohammad Areeb Siddiqui

2
หรือ: destination.appendChild (ต้นฉบับ) โดยใช้ javascript ธรรมดา
ลุค

เราสามารถทำได้โดยใช้ CSS? เป็นไปได้ไหม
Rajumar Samala

6
@RajKumarSamala CSS ไม่สามารถเปลี่ยนโครงสร้างของ HTML ได้เพียง แต่การนำเสนอเท่านั้น
Mark Richman

คำตอบ:


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ในความพยายามของเขา / เธอในการปรับปรุงโพสต์ - แต่นั่นผิด!
Bekim Bacaj

6
มันน่าอัศจรรย์ที่ผู้คนยังคิดว่า jQuery เท่ากับ JavaScript ไม่จำเป็นต้องใช้ jQuery อีกต่อไปในปี 2560 จริงๆ
2560

2
ไม่จำเป็นต้อง jQuery ในปี 2560 แต่บางครั้งมันก็ช่วยให้ใช้สิ่งที่เบากว่าและคล้ายกันสำหรับงานที่คุณพบว่าตัวเองทำซ้ำแล้วซ้ำอีกในทุกโครงการ ฉันใช้ cash-dom เป็นวิธีที่ง่ายในการฟัง document.ready, window.load เหตุการณ์ในเบราว์เซอร์ที่เป็นมิตร ง่าย peasy
eballeste

1
เปลี่ยนเป็นคำตอบที่ยอมรับตอนนี้ก็คือปี 2020 :)
Mark Richman

1
มันน่าอัศจรรย์ที่ผู้คนยังคิดว่า jQuery เท่ากับ JavaScript ไม่จำเป็นต้องใช้ jQuery อีกต่อไปในปี 2020 จริงๆ
ii iml0sto1

1794

คุณอาจต้องการใช้appendToฟังก์ชัน (ซึ่งเพิ่มในส่วนท้ายขององค์ประกอบ):

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

อีกทางเลือกหนึ่งคุณสามารถใช้prependToฟังก์ชั่น (ซึ่งเพิ่มไว้ที่จุดเริ่มต้นขององค์ประกอบ):

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

ตัวอย่าง:


23
คำเตือนว่าสิ่งนี้อาจทำงานได้ไม่ถูกต้องใน jQuery mobile เพราะมันอาจสร้างองค์ประกอบอื่นแทน
Jordan Reiter

32
appen ทำอย่างไรในการสร้างสำเนาหรือย้าย div ทั้งหมดไปยังปลายทาง (เพราะถ้ามันคัดลอกมันจะสร้างความผิดพลาดเมื่อเรียก div ด้วยรหัส)

50
นี่คือบทความที่ยอดเยี่ยมเกี่ยวกับการลบการเปลี่ยนและการย้ายองค์ประกอบใน jQuery: elated.com/articles/jquery-removing-replacing-moving-elements
xhh

42
หมายเหตุเอกสารประกอบ jQuery สำหรับภาคผนวกเพื่อระบุองค์ประกอบที่ถูกย้าย: 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')

สังเกตการใช้งานของ. debach () เมื่อคัดลอกโปรดระวังว่าคุณไม่ได้ทำซ้ำ ID


86
คำตอบที่ดีที่สุด คำตอบที่ยอมรับสร้างสำเนาไม่ย้ายองค์ประกอบเหมือนคำถามที่ถาม
paulscode

97
ขออภัย แต่คำตอบที่ได้รับการยอมรับของ Andrew Hare นั้นถูกต้อง - การถอดไม่จำเป็น ลองใช้ใน JSFiddle ของ Pixic ด้านบน - หากคุณลบการโทรออกมันจะทำงานเหมือนกันทุกประการนั่นคือมันเป็นการเคลื่อนไหวไม่ใช่การคัดลอก นี่คือทางแยกที่มีการเปลี่ยนแปลงเพียงครั้งเดียว: jsfiddle.net/D46y5 ดัง ที่บันทึกไว้ใน API: api.jquery.com/appendTo : "หากองค์ประกอบที่เลือกด้วยวิธีนี้ถูกแทรกลงในตำแหน่งเดียวที่อื่นใน DOM มันจะถูกย้าย เข้าสู่เป้าหมาย (ไม่ลอกแบบ) และชุดใหม่ที่ประกอบด้วยองค์ประกอบที่แทรกจะถูกส่งคืน "
John - ไม่ใช่ A จำนวน

8
@ John-NotANumber ถูกต้อง - ไม่จำเป็นต้องถอด () ที่นี่ คำตอบที่ยอมรับนั้นดีที่สุดคุณเพียงแค่ต้องอ่านเอกสารอย่างถูกต้อง
LeonardChallis

11
เอกสารภาคผนวกยังกล่าวด้วยว่า: "หากมีองค์ประกอบเป้าหมายมากกว่าหนึ่งองค์ประกอบสำเนาโคลนขององค์ประกอบที่แทรกจะถูกสร้างขึ้นสำหรับแต่ละเป้าหมายหลังจากชุดแรกและชุดใหม่ (องค์ประกอบดั้งเดิมบวกโคลน) จะถูกส่งคืน" ดังนั้นในกรณีทั่วไปวิธีนี้สามารถสร้างสำเนาได้!
Vincent Pazeller

ที่ดี! หรือคุณสามารถใช้สิ่งนี้เพื่อเจาะจงมากขึ้นเกี่ยวกับสถานที่ที่จะย้าย$('#nodeToMove').insertAfter('#insertAfterThisElement');
Victor Augusto

108

ฉันเพิ่งใช้:

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

ซึ่งผมคว้ามาจากที่นี่


7
แยกออกมีประโยชน์เมื่อคุณต้องการที่จะยึดองค์ประกอบและแทรกในภายหลัง แต่ในตัวอย่างของคุณคุณแทรกมันอีกครั้งทันที
ทิมBüthe

1
ฉันเกรงว่าฉันจะไม่อ่านสิ่งที่คุณได้รับคุณสามารถให้รหัสตัวอย่างได้หรือไม่?
kjc26ster

1
ฉันหมายถึงการเสริมเพื่อแยกองค์ประกอบจากตำแหน่งเดิมและแทรกที่องค์ประกอบใหม่ ฟังก์ชั่นแยกออกในทางกลับกันเพียงแค่แยกองค์ประกอบที่เลือกและคุณสามารถบันทึกไว้ในตัวแปรเพื่อแทรกลงใน DOM ในเวลาต่อมา ประเด็นก็คือการโทรออกของคุณไม่จำเป็น ลบมันออกแล้วคุณจะได้ผลเหมือนเดิม
ทิมBüthe

1
ไม่น่าเชื่อว่าการแก้ไขเปลี่ยนแปลงคำตอบนี้สมบูรณ์ไปยังจุดที่คำตอบอื่นได้รับเพิ่มอีกหนึ่งปีต่อมา (เหมือนเดิม) และได้ 800+ upvotes ...
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'))
Gunar Gessner

6
@ GunarC.Gessner สมมติว่าคุณต้องแก้ไขวัตถุต้นฉบับก่อนที่จะเพิ่มไปยังวัตถุปลายทางจากนั้นวิธีที่ดีที่สุดคือการใช้ส่วนที่เป็นวัตถุจินตภาพและไม่ได้เป็นส่วนหนึ่งของต้นไม้ DOM คุณจะได้ประสิทธิภาพที่ดีขึ้นเมื่อทำการแก้ไข แหล่งที่มาของวัตถุเมื่อมันได้รับการเปลี่ยนจากสถานที่เดิม (ตอนนี้มันอยู่ในส่วน) แทนที่จะแก้ไขในสถานที่เริ่มต้นก่อนที่จะผนวกมัน
Ali Bassam

5
ฉันต้องการเพิ่มสำหรับความเกี่ยวข้องของการเสนอโซลูชัน JavaScript ที่บริสุทธิ์ ไม่ควรสันนิษฐานว่า jQuery ใช้งานอยู่เสมอ
Alexander Fradiani

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.

ฉันพบว่าตัวหนาทั้งหมดอ่านยาก แต่นี่เป็นคำตอบที่ให้ข้อมูลมากที่สุด
Michael Scheper

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');

ลองใช้codepen


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
และแบ่งผู้ฟังเหตุการณ์ในองค์ประกอบที่ย้าย
Igor Pomaranskiy

4

ฉันสังเกตเห็นว่าการรั่วไหลของหน่วยความจำขนาดใหญ่และความแตกต่างระหว่างinsertAfter& afterหรือinsertBefore& before.. หากคุณมีองค์ประกอบ DOM จำนวนมากหรือคุณจำเป็นต้องใช้after()หรือbefore()ภายในเหตุการณ์ MouseMoveหน่วยความจำเบราว์เซอร์อาจเพิ่มขึ้นและการทำงานต่อไปจะช้าลงจริง ๆ

วิธีการแก้ปัญหาที่ผมเคยมีประสบการณ์เพียงคือการใช้ inserBefore แทนbefore()และ InsertAfter after()แทน


ดูเหมือนว่าปัญหาที่ขึ้นกับการนำไปใช้ของเครื่องมือ JavaScript คุณเห็นเวอร์ชันของเบราว์เซอร์และโปรแกรมเอ็นจินนี้
Mark Richman

1
ฉันใช้ Chrome รุ่น 36.0.1985.125 และใช้ jQuery v1.11.1 ฉันผูกฟังก์ชั่นกับเหตุการณ์ mousemove ซึ่งจะย้าย DIV แบบง่าย ๆ เพื่อลดระดับหรือเพิ่มองค์ประกอบที่เมาส์วางอยู่ ดังนั้นกิจกรรมและฟังก์ชั่นนี้จะทำงานในขณะที่คุณลากเคอร์เซอร์ หน่วยความจำรั่วเกิดขึ้นหลังจาก () และก่อนหน้า () หากคุณเลื่อนเคอร์เซอร์ไปที่ 30 วินาทีและจะหายไปถ้าฉันใช้ insertAfter & insertBefore แทน
spetsnaz

1
ฉันเปิดบั๊กกับ Google บนอันนั้น
Mark Richman

2

คุณสามารถใช้จาวาสคริปต์ที่บริสุทธิ์โดยใช้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()กล่าวถึงในบทความนี้ ดังนั้นคำถามของ OP อาจจะแก้ไขได้ด้วยวิธีนี้ (นั่นคือถ้า<div id="destination" />ยังไม่มีอยู่วิธีต่อไปนี้จะสร้าง wrapper ดังกล่าวตั้งแต่เริ่มต้น - OP ไม่ชัดเจนเกี่ยวกับว่า wrapper มีอยู่แล้วหรือไม่):

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

มันฟังดูมีแนวโน้ม อย่างไรก็ตามเมื่อฉันพยายามทำ$("[id^=row]").wrapAll("<fieldset></fieldset>")หลายโครงสร้างซ้อนกันเช่นนี้

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

ได้อย่างถูกต้อง wraps เหล่านั้น<div>...</div>และแต่อย่างใดออกใบ<input>...</input> <label>...</label>ดังนั้นฉันก็เลยใช้ชัดแจ้ง$("row1").append("#a_predefined_fieldset")แทน ดังนั้น YMMV

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.