Phần tử di chuyển JavaScript trong DOM


97

Giả sử tôi có ba <div>phần tử trên một trang. Làm cách nào để hoán đổi vị trí của thứ nhất và thứ ba <div>? jQuery là tốt.

Câu trả lời:


110

Tầm thường với jQuery

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

Nếu bạn muốn làm điều đó nhiều lần, bạn sẽ cần sử dụng các bộ chọn khác nhau vì các div sẽ giữ lại id của chúng khi chúng được di chuyển xung quanh.

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

1
@Ionut - vấn đề là nó phụ thuộc vào vị trí tương đối của các phần tử. Khi bạn thay đổi thứ tự, bạn không thể tìm thấy thứ nhất và thứ ba theo id của chúng nữa và cần phải tìm ra cách khác. Câu trả lời của tôi chỉ nhằm minh họa chức năng của các phương thức để hoàn thành nhiệm vụ được yêu cầu, không phải là một giải pháp toàn diện để hoán đổi div đầu tiên và div thứ ba trong một tập hợp với số lần tùy ý.
tvanfosson

Xin chào các bạn, một câu hỏi nhanh: Có cách nào dễ dàng để đặt lại về trạng thái Dom ban đầu sau khi hoàn tất hàm jquery ở trên không?
Vikita

@Vikita - vâng, lưu HTML gốc rồi khôi phục lại. Bạn có thể phải đăng ký lại bất kỳ trình xử lý nào nếu chúng đã được áp dụng trực tiếp thay vì được ủy quyền cho phần tử cao hơn. Ví dụ:var html = $('#container').html(); ...; $('#container').html(html);
tvanfosson

171

Không cần thiết phải sử dụng thư viện cho một nhiệm vụ tầm thường như vậy:

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

Điều này tính đến thực tế là getElementsByTagNametrả về một NodeList trực tiếp được cập nhật tự động để phản ánh thứ tự của các phần tử trong DOM khi chúng được thao tác.

Bạn cũng có thể sử dụng:

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

và có nhiều phép hoán vị có thể có khác, nếu bạn muốn thử nghiệm:

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

ví dụ :-)


15
Đúng, nhưng thật khó để tranh luận về sự sang trọng và dễ đọc mà thứ gì đó như jQuery cung cấp - chưa kể đến các khả năng nâng cao ngay từ đầu.
Joe Malloy điên rồ,

13
Vâng, nhưng ai chỉ làm một việc này?
tvanfosson

1
... hoặc chỉ có 3 div trên trang
Ryan Florence

38
@everybody: câu hỏi ban đầu hỏi cách hoán đổi div thứ ba và div đầu tiên trên một trang có ba div. Đó là câu hỏi tôi đã trả lời. Nếu OP đã có một câu hỏi phức tạp hơn, họ nên đã yêu cầu nó, và họ sẽ có được một câu trả lời phức tạp hơn ;-)
NickFitz

26
Nếu ai đang tìm kiếm điều này trong năm 2014, hãy xem xét câu trả lời này. jQuery đã hữu ích trước đây, nhưng bây giờ nó không còn hữu ích nữa, vì các trình duyệt đã được chuẩn hóa, vì vậy không cần thêm thư viện 80 kb chỉ để thực hiện một tác vụ đơn giản như vậy. Ngoài ra, bạn không nhận được để biết những gì DOM thực sự là cho đến khi bạn thử nó mà không cần jQuery :)
gustavohenke

29

.trước và sau

Sử dụng vani JS hiện đại! Cách tốt hơn / sạch hơn trước đây. Không cần phải tham chiếu đến cha mẹ.

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

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

Hỗ trợ trình duyệt - 94,23% toàn cầu tính đến tháng 7 năm 20


Chưa có hỗ trợ Internet Explorer.
justnorris

11
Bạn không cần phải viết mã ít bảo trì hơn để hỗ trợ mọi người trên các trình duyệt cũ hoặc không phù hợp với tiêu chuẩn. Trừ khi bạn làm việc trong doanh nghiệp, vài người dùng sẽ bỏ lỡ
Gibolt

Các phương pháp khác cũng hoạt động liên quan đến khả năng bảo trì, đặc biệt là khi gói trong một hàm sạch đẹp. Tôi là tất cả để viết mã hiện đại, nhưng điều này đang chảy máu. Thật tuyệt khi biết tương lai sẽ ra sao, nhưng tôi không thích bất cứ thứ gì liên quan đến IE - điều quan trọng là phải biết tác động của quyết định của bạn là gì. Trong trường hợp này - một ứng dụng web bị hỏng trong bất kỳ trình duyệt IE nào. Nếu điều đó ổn với bạn - thật tuyệt! Tôi thêm những nhận xét chỉ để thông báo cho bất cứ ai googling :) này
justnorris

1
Vậy 27% người dùng là mấy người ? Chúng ta đang nói hàng triệu người!
SandRock

5
Trong một năm, con số đó sẽ gần 10%. Nó chủ yếu là doanh nghiệp, chính phủ và các thiết bị di động cũ hơn. Điều này thường có nghĩa là thiết bị phi cá nhân hoặc người dùng ít thiên về kỹ thuật. Các câu trả lời sẽ được mong đợi để chúng tôi không bị mắc kẹt trong việc phát triển trong năm 2009.
Gibolt

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; 
};

và sử dụng nó như thế này:

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

nếu bạn không muốn sử dụng jQuery, bạn có thể dễ dàng điều chỉnh hàm.


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

Chức năng này có vẻ lạ, nhưng nó phụ thuộc rất nhiều vào các tiêu chuẩn để hoạt động đúng. Trên thực tế, nó có vẻ hoạt động tốt hơn phiên bản jQuery mà tvanfosson đã đăng có vẻ như chỉ hoán đổi hai lần.

Nó dựa vào những tiêu chuẩn đặc biệt nào?

insertBefore Chèn nút newChild trước refChild nút con hiện có. Nếu refChild là null, hãy chèn newChild vào cuối danh sách con. Nếu newChild là một đối tượng DocumentFragment, tất cả các đối tượng con của nó sẽ được chèn, theo cùng một thứ tự, trước refChild. Nếu newChild đã có trong cây, nó sẽ bị loại bỏ trước tiên.


0

Cách tiếp cận jquery được đề cập ở trên sẽ hoạt động. Bạn cũng có thể sử dụng JQuery và CSS .Say, ví dụ: trên Div, bạn đã áp dụng class1 và div2, bạn đã áp dụng class class2 (ví dụ: mỗi lớp css cung cấp vị trí cụ thể trên trình duyệt), bây giờ bạn có thể hoán đổi các lớp bằng cách sử dụng jquery hoặc javascript (điều đó sẽ thay đổi vị trí)


0

Xin lỗi vì đã đụng chuỗi này, tôi đã vấp phải sự cố "hoán đổi các phần tử DOM" và đã giải quyết một chút

Kết quả là một "giải pháp" jQuery-native có vẻ rất đẹp (tiếc là tôi không biết điều gì đang xảy ra ở nội bộ jQuery khi thực hiện điều này)

Mật mã:

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

Tài liệu jQuery nói rằng điều đó insertAfter() sẽ di chuyển phần tử và không sao chép nó

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.