องค์ประกอบการย้าย JavaScript ใน DOM


99

สมมติว่าฉันมี<div>องค์ประกอบสามอย่างในหนึ่งหน้า ฉันจะสลับตำแหน่งของครั้งแรกและครั้งที่สามได้อย่างไร<div>อย่างไร? jQuery ใช้ได้

คำตอบ:


111

เล็กน้อยกับjQuery

$('#div1').insertAfter('#div3');
$('#div3').insertBefore('#div2');

หากคุณต้องการทำซ้ำ ๆ คุณจะต้องใช้ตัวเลือกที่แตกต่างกันเนื่องจาก div จะยังคงรักษารหัสไว้เมื่อมีการเคลื่อนย้าย

$(function() {
    setInterval( function() {
        $('div:first').insertAfter($('div').eq(2));
        $('div').eq(1).insertBefore('div:first');
    }, 3000 );
});

1
@Ionut - จุดที่มันขึ้นอยู่กับตำแหน่งสัมพัทธ์ขององค์ประกอบ เมื่อคุณเปลี่ยนลำดับคุณจะไม่สามารถค้นหาลำดับที่หนึ่งและสามด้วยรหัสของพวกเขาได้อีกต่อไปและจำเป็นต้องหาวิธีอื่น คำตอบของฉันมีไว้เพื่อแสดงให้เห็นถึงฟังก์ชันการทำงานของวิธีการเพื่อให้บรรลุภารกิจที่ร้องขอเท่านั้นไม่ใช่วิธีแก้ปัญหาที่ครอบคลุมในการสลับ div ที่หนึ่งและสามในจำนวนครั้งที่กำหนดโดยพลการ
tvanfosson

สวัสดีครับคำถามสั้น ๆ : มีวิธีง่ายๆในการรีเซ็ตกลับสู่สถานะ Dom ดั้งเดิมเมื่อฟังก์ชั่น jquery ข้างต้นเสร็จสมบูรณ์หรือไม่?
Vikita

@Vikita - ใช่บันทึก HTML ดั้งเดิมแล้วกู้คืน คุณอาจต้องสมัครตัวจัดการใด ๆ อีกครั้งหากนำไปใช้โดยตรงแทนการมอบหมายให้กับองค์ประกอบที่สูงกว่า ตัวอย่างเช่นvar html = $('#container').html(); ...; $('#container').html(html);
tvanfosson

173

ไม่จำเป็นต้องใช้ไลบรารีสำหรับงานที่ไม่สำคัญ:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[2].parentNode.insertBefore(divs[2], divs[0]); // order: third, first, second
divs[2].parentNode.insertBefore(divs[2], divs[1]); // order: third, second, first

สิ่งนี้คำนึงถึงข้อเท็จจริงที่getElementsByTagNameส่งคืน NodeList ที่ใช้งานอยู่ซึ่งได้รับการอัปเดตโดยอัตโนมัติเพื่อแสดงลำดับขององค์ประกอบใน DOM เมื่อมีการจัดการ

คุณยังสามารถใช้:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[0].parentNode.appendChild(divs[0]);           // order: second, third, first
divs[1].parentNode.insertBefore(divs[0], divs[1]); // order: third, second, first

และมีการเรียงสับเปลี่ยนที่เป็นไปได้อื่น ๆ อีกมากมายหากคุณรู้สึกอยากทดลอง:

divs[0].parentNode.appendChild(divs[0].parentNode.replaceChild(divs[2], divs[0]));

ตัวอย่างเช่น :-)


16
จริง แต่มันยากที่จะโต้แย้งกับความสง่างามและความสามารถในการอ่านที่ jQuery มีให้ - ไม่ต้องพูดถึงความสามารถที่เพิ่มขึ้นนอกกรอบ
Crazy Joe Malloy

13
ใช่ แต่ใครทำสิ่งนี้เพียงคนเดียว?
tvanfosson

1
... หรือมีเพียง 3 div บนหน้า
Ryan Florence

38
@everybody: คำถามเดิมถามว่าจะสลับ div ตัวที่สามและตัวแรกในหน้าที่มี div สามตัวได้อย่างไร นั่นคือคำถามที่ฉันตอบ หาก OP มีคำถามที่ซับซ้อนกว่านี้พวกเขาควรจะถามมันและพวกเขาจะได้รับคำตอบที่ซับซ้อนมากขึ้น ;-)
NickFitz

27
หากใครที่กำลังมองหาสิ่งนี้ในปี 2014 โปรดพิจารณาคำตอบนี้ jQuery มีประโยชน์ในตอนนั้น แต่ตอนนี้มันไม่มีประโยชน์อีกต่อไปแล้วเนื่องจากเบราว์เซอร์เป็นมาตรฐานดังนั้นจึงไม่จำเป็นต้องเพิ่มไลบรารี 80 kb เพื่อทำงานง่ายๆเช่นนี้ นอกจากนี้คุณยังไม่รู้ว่า DOM คืออะไรจนกว่าคุณจะลองโดยไม่ใช้ jQuery :)
gustavohenke

32

.ก่อนและหลัง

ใช้วานิลลาสมัยใหม่ JS! ดีกว่า / สะอาดกว่าเดิม ไม่จำเป็นต้องอ้างอิงผู้ปกครอง

const div1 = document.getElementById("div1");
const div2 = document.getElementById("div2");
const div3 = document.getElementById("div3");

div2.after(div1);
div2.before(div3);

การรองรับเบราว์เซอร์ - 95% ทั่วโลก ณ ต.ค. 20


ยังไม่มีการสนับสนุน Internet Explorer
justnorris

12
คุณไม่ควรเขียนโค้ดที่ดูแลรักษาได้น้อยลงเพื่อรองรับผู้ใช้เบราว์เซอร์ที่เก่าหรือไม่เป็นไปตามมาตรฐาน หากคุณไม่ได้ทำงานในองค์กรผู้ใช้เพียงไม่กี่คนที่จะพลาด
Gibolt

วิธีอื่น ๆ ก็ใช้ได้ผลเช่นกันในเรื่องการบำรุงรักษาโดยเฉพาะอย่างยิ่งเมื่อห่อหุ้มด้วยฟังก์ชันที่สะอาดดี ฉันเขียนโค้ดสมัยใหม่ทั้งหมด แต่นี่เป็นเรื่องที่น่าสนใจ เป็นเรื่องดีที่รู้ว่าอนาคตจะเป็นอย่างไร แต่เท่าที่ฉันไม่ชอบอะไรที่เกี่ยวข้องกับ IE - สิ่งสำคัญคือต้องรู้ว่าผลกระทบของการตัดสินใจของคุณคืออะไร ในกรณีนี้ - เว็บแอปที่ใช้งานไม่ได้ในเบราว์เซอร์ IE ใด ๆ ถ้าคุณไม่เป็นไร - เยี่ยมมาก! ฉันเพิ่มความคิดเห็นเพื่อแจ้งให้ทุกคนทราบว่า googling นี้ :)
justnorris

1
ผู้ใช้ 27% จึงเป็นผู้ใช้ไม่กี่คน ? เรากำลังพูดถึงล้าน!
SandRock

6
ในหนึ่งปีตัวเลขนั้นจะใกล้เคียงกับ 10% ส่วนใหญ่เป็นอุปกรณ์องค์กรรัฐบาลและอุปกรณ์เคลื่อนที่รุ่นเก่า ซึ่งมักจะหมายถึงอุปกรณ์ที่ไม่ใช่ของส่วนตัวหรือผู้ใช้ที่มีความโน้มเอียงทางเทคนิคน้อยกว่า คำตอบควรมองไปข้างหน้าเพื่อที่เราจะได้ไม่ติดขัดในการพัฒนาในปี 2552
กิโบลต์

11
jQuery.fn.swap = function(b){ 
    b = jQuery(b)[0]; 
    var a = this[0]; 
    var t = a.parentNode.insertBefore(document.createTextNode(''), a); 
    b.parentNode.insertBefore(a, b); 
    t.parentNode.insertBefore(b, t); 
    t.parentNode.removeChild(t); 
    return this; 
};

และใช้มันดังนี้:

$('#div1').swap('#div2');

หากคุณไม่ต้องการใช้ jQuery คุณสามารถปรับฟังก์ชั่นได้อย่างง่ายดาย


5
var swap = function () {
    var divs = document.getElementsByTagName('div');
    var div1 = divs[0];
    var div2 = divs[1];
    var div3 = divs[2];

    div3.parentNode.insertBefore(div1, div3);
    div1.parentNode.insertBefore(div3, div2);
};

ฟังก์ชั่นนี้อาจดูแปลก แต่ต้องอาศัยมาตรฐานเป็นอย่างมากเพื่อให้ทำงานได้อย่างถูกต้อง ในความเป็นจริงมันอาจจะทำงานได้ดีกว่าเวอร์ชั่น jQuery ที่ tvanfosson โพสต์ซึ่งดูเหมือนว่าจะทำการ swap เพียงสองครั้ง

มันขึ้นอยู่กับลักษณะเฉพาะมาตรฐานอะไรบ้าง?

insertBefore แทรกโหนด newChild ก่อนโหนดลูกที่มีอยู่ refChild ถ้า refChild เป็นโมฆะให้ใส่ newChild ที่ท้ายรายชื่อเด็ก ถ้า newChild เป็นอ็อบเจ็กต์ DocumentFragment ลูกของมันทั้งหมดจะถูกแทรกในลำดับเดียวกันก่อนที่จะ refChild ถ้า newChild อยู่ในแผนภูมิแล้วระบบจะลบออกก่อน


0

วิธี Jquery ที่กล่าวถึงด้านบนจะใช้งานได้ คุณยังสามารถใช้ JQuery และ CSS ได้อีกด้วยพูดเช่นใน Div หนึ่งที่คุณได้ใช้ class1 และ div2 คุณได้ใช้คลาส class2 (เช่นแต่ละคลาสของ css ให้ตำแหน่งเฉพาะบนเบราว์เซอร์) ตอนนี้คุณสามารถแลกเปลี่ยนคลาสโดยใช้ jquery หรือ javascript (ที่จะเปลี่ยนตำแหน่ง)


0

ขออภัยที่ทำให้เธรดนี้สะดุดฉันสะดุดกับปัญหา "สลับองค์ประกอบ DOM" และเล่นไปสักหน่อย

ผลลัพธ์ที่ได้คือ "โซลูชัน" แบบ jQuery-native ซึ่งดูเหมือนจะสวยจริงๆ (น่าเสียดายที่ฉันไม่รู้ว่าเกิดอะไรขึ้นที่ jQuery ภายในเมื่อทำสิ่งนี้)

รหัส:

$('#element1').insertAfter($('#element2'));

เอกสาร jQuery ระบุว่าinsertAfter() ย้ายองค์ประกอบและไม่โคลน

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