Xóa phần tử theo id


1129

Khi xóa một phần tử bằng JavaScript tiêu chuẩn, trước tiên bạn phải chuyển đến phần tử mẹ của nó:

var element = document.getElementById("element-id");
element.parentNode.removeChild(element);

Trước tiên tôi phải vào nút cha có vẻ hơi kỳ lạ, có lý do gì JavaScript hoạt động như thế này không?


534
Như James đã nói, DOM không hỗ trợ loại bỏ một đối tượng trực tiếp. Bạn phải đi đến cha mẹ của nó và loại bỏ nó từ đó. Javascript sẽ không để một phần tử tự sát, nhưng nó cho phép vô cùng ...
Mark Henderson

21
Có một lý do? Richard Feynman nói không . (Vâng, bằng chứng kỹ thuật rất dễ thấy nếu bạn đã viết bất kỳ chương trình cấu trúc cây nào. Đứa trẻ phải thông báo cho cha mẹ bằng mọi cách nếu không cấu trúc cây có thể bị phá vỡ. Vì dù sao nó cũng phải làm điều đó, nếu nó cung cấp cho bạn chức năng một dòng , nó chỉ là một chức năng thuận tiện cho bạn mà bạn cũng có thể tự xác định.)
kizzx2

6
Lý do duy nhất tôi thấy là luôn có một phần tử gốc trong tài liệu xml / xhtml, vì vậy bạn sẽ không thể xóa nó vì nó không có cha mẹ
Alex K

5
Tôi khá thích cách giải quyết của Johan và tôi không chắc tại sao các chức năng đó không được cung cấp nguyên bản. Bằng chứng là số lượng người xem, đó là một hoạt động rất phổ biến.
Zaz

12
Bạn có thể sử dụng element.remove()trực tiếp kể từ ES5. Bạn không cần cha mẹ!
Gibolt

Câu trả lời:


659

Tôi biết rằng việc tăng cường các chức năng DOM gốc không phải lúc nào cũng là giải pháp tốt nhất hoặc phổ biến nhất, nhưng điều này hoạt động tốt cho các trình duyệt hiện đại.

Element.prototype.remove = function() {
    this.parentElement.removeChild(this);
}
NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
    for(var i = this.length - 1; i >= 0; i--) {
        if(this[i] && this[i].parentElement) {
            this[i].parentElement.removeChild(this[i]);
        }
    }
}

Và sau đó bạn có thể loại bỏ các yếu tố như thế này

document.getElementById("my-element").remove();

hoặc là

document.getElementsByClassName("my-elements").remove();

Lưu ý: giải pháp này không hoạt động cho IE 7 trở xuống. Để biết thêm thông tin về việc mở rộng DOM, hãy đọc bài viết này .

EDIT : Xem xét câu trả lời của tôi vào năm 2019, node.remove()đã đến để giải cứu và có thể được sử dụng như sau (không có polyfill ở trên):

document.getElementById("my-element").remove();

hoặc là

[...document.getElementsByClassName("my-elements")].map(n => n && n.remove());

Các chức năng này có sẵn trong tất cả các trình duyệt hiện đại (không phải IE). Đọc thêm về MDN .


3
Không nên là [document.getElementsByClassName ("my-yếu tố") [0] .remove (); ] Tôi nghĩ rằng hàm remove () ist không được thực hiện bởi các mảng. Để xóa tất cả các phần tử của một lớp hoặc bất kỳ bộ chọn nào trả về một mảng, bạn phải lặp qua tất cả các phần tử và gọi remove () trên mỗi phần tử.
Sedat Kilinc

1
@SedatKilinc, bạn đã thử đoạn trích thực tế chưa? Không có mảng liên quan, mà là NodeListhoặc HTMLCollectionlà tập hợp các phần tử giống như mảng. Định nghĩa phương thức thứ hai cho phép loại bỏ các "bộ phần tử" này.
Johan Dettmar

1
Chạy cái này trong bảng điều khiển chrome dường như chỉ xóa một phần tử tại một thời điểm khi sử dụng document.getElementsByClassName("my-elements").remove();. Chỉnh sửa: thực sự nó xóa một bó nhưng yêu cầu chạy lại để kết thúc. Hãy thử nó trên trang này với lớp "bình luận-sao chép".
DanielST 7/07/2015

2
@slicedtoad bạn nói đúng, xấu của tôi. Tôi đã sửa đổi hàm để lặp ngược thông qua các phần tử. Có vẻ để làm việc tốt. Hành vi bạn đang nói đến rất có thể do các chỉ mục cập nhật gây ra.
Johan Dettmar 8/07/2015

1
Đừng làm điều này. Đơn giản chỉ cần loại bỏ các mục theo cách ngôn ngữ dự định. Bất cứ ai quen thuộc với phân tích cú pháp XML sẽ nhận ra sự cần thiết phải đến cha mẹ để xóa con cái. HTML là một siêu bộ của XML (sắp xếp).
Hal50000

283

Crossbrowser và IE> = 11:

document.getElementById("element-id").outerHTML = "";

3
Đây có vẻ là giải pháp đơn giản nhất, đáng tin cậy nhất và nhanh nhất. Tôi không cần phải xóa phần tử vì vậy tôi bỏ qua dòng cuối cùng, nhưng không nên thêm bất kỳ chi phí nào cả .. Lưu ý : Tôi đã tìm thấy phần này trong khi cố gắng tìm một phần $.readythay thế nhanh hơn js cho noscriptcác thẻ. Để sử dụng nó theo cách tôi muốn, tôi phải bọc nó trong setTimeouthàm 1ms . Điều này giải quyết tất cả các vấn đề của tôi cùng một lúc. Gracias.
DGO

Hãy nhớ rằng outerHTMLvẫn là một bổ sung (er) mới cho tiêu chuẩn. Nếu bạn đang tìm kiếm hỗ trợ trên bất kỳ phần mềm nào> 6 tại thời điểm viết, bạn sẽ cần một giải pháp khác. Các removechức năng được đề cập bởi những người khác là một trường hợp tương tự. Như thường lệ, nó an toàn để thực hiện một polyfill.
Super Cat

delete elementkhông làm gì vì bạn không thể xóa các biến trong JS, chỉ các khóa;) Hãy tự kiểm tra xem nó không hoạt động console.log(element)sau delete element...
Ivan Kleshnin

2
Đây là một chút chậm hơn removeChild(khoảng 6-7% trên hệ thống của tôi). Xem jsperf.com/clear-outerhtml-v-removechild/2
Alejandro García Iglesias

1
Điều này có thể để lại một khoảng trống nơi iframe được sử dụng nếu đó là những gì bạn đang cố xóa.
lacostenycoder

164

Bạn có thể tạo một removechức năng để bạn không phải suy nghĩ về nó mỗi lần:

function removeElement(id) {
    var elem = document.getElementById(id);
    return elem.parentNode.removeChild(elem);
}

12
Nếu bạn muốn một lớp lót mà không đi toàn cầu, bạn có thể thay đổi elemthành remove.elem. Bằng cách đó, hàm tham chiếu chính nó, vì vậy bạn không phải tạo một biến toàn cục khác. :-)
twiz

4
Vì vậy, tại sao bạn cần phải trả lại elem? Tại sao khôngfunction remove(id) { document.getElementById(id).parentNote.removeChild(document.getElementById(id)); }
Zach Lysobey

4
@ZachL: Trong khi giải pháp của bạn có vẻ rõ ràng hơn, nó thực hiện hai lần tra cứu DOM chậm hơn và điều mà các giải pháp khác dường như muốn tránh.
Wk_of_Angmar

3
Không hoạt động. Quá nhiều lỗi. Điều này hoạt động: var elem = document.getEuityById ('id'); elem.parentNode.removeChild (elem);
Trận đấu Mitch

2
Wow, tại sao quá phức tạp. Chỉ cần truyền chính phần tử cho hàm thay vì chuỗi id. Bằng cách này, phần tử có thể truy cập được trong toàn bộ chức năng cộng với nó nằm trong một lớp lót
David Fariña

97

Đó là những gì DOM hỗ trợ . Tìm kiếm trang đó để "xóa" hoặc "xóa" và removeChild là trang duy nhất xóa nút.


13
Điều đó trả lời câu hỏi ban đầu của tôi, nhưng tại sao JavaScript hoạt động như thế này?
Zaz

5
Tôi chỉ đoán ở đây, nhưng tôi sẽ cho rằng nó phải làm với quản lý bộ nhớ. Nút cha rất có thể chứa một danh sách các con trỏ tới các nút con. Nếu bạn vừa xóa một nút (không sử dụng cha), cha mẹ vẫn sẽ giữ con trỏ và gây rò rỉ bộ nhớ. Vì vậy, api buộc bạn phải gọi một chức năng trên cha mẹ để xóa con. Điều này cũng tốt vì nó có thể đưa cây xuống qua các nút con gọi loại bỏ trên mỗi nút và không bị rò rỉ bộ nhớ.
Chadams

2
này các bạn, mặc dù tài liệu tham khảo đó không có cái này, tôi đã vô tình tìm thấy nó. Viết element.remove();sẽ làm việc. Có lẽ đó là một cái gì đó mới. Nhưng lần đầu tiên cho tôi và nó hoạt động. Tôi nghĩ rằng nó nên hoạt động luôn vì nó rất cơ bản phải có công cụ.
Muhammad Umer

1
Nhưng nó không hoạt động trong IE7 trở xuống. Từ IE7 trở xuống, remove () không hoạt động
fanfan1609

1
Nếu tôi phải đoán, lý do nó hoạt động như thế này là do các phần tử DOM không thể tự xóa. Bạn đang gỡ tấm thảm tục ngữ từ dưới chân nó. Bạn phải loại bỏ nó khỏi container. Ít nhất đó là cách tôi cố gắng nghĩ về nó.
PhilT

82

DOM được tổ chức trong một cây các nút, trong đó mỗi nút có một giá trị, cùng với một danh sách các tham chiếu đến các nút con của nó. Vì vậy, element.parentNode.removeChild(element)bắt chước chính xác những gì đang xảy ra trong nội bộ: Đầu tiên bạn vào nút cha, sau đó xóa tham chiếu đến nút con.

Kể từ DOM4, một hàm trợ giúp được cung cấp để làm điều tương tự : element.remove(). Điều này hoạt động trong 87% trình duyệt (tính đến năm 2016), nhưng không phải IE 11. Nếu bạn cần hỗ trợ các trình duyệt cũ hơn, bạn có thể:


2
Vui lòng không "sửa đổi các hàm DOM gốc" .
Emile Bergeron

36

Để xóa một phần tử:

 var elem = document.getElementById("yourid");
 elem.parentElement.removeChild(elem);

Để loại bỏ tất cả các phần tử với ví dụ một tên lớp nhất định:

 var list = document.getElementsByClassName("yourclassname");
 for(var i = list.length - 1; 0 <= i; i--)
 if(list[i] && list[i].parentElement)
 list[i].parentElement.removeChild(list[i]);

Điều này được bao phủ bởi các câu trả lời hiện có.
KyleMit

4
+1 Ví dụ đơn giản về loại bỏ theo tên lớp. Điều này không được bao phủ tốt bởi các câu trả lời khác
Louise Eggleton

Tại sao if(list[i] && list[i].parentElement)dòng cần thiết? Không phải sự tồn tại của mỗi phần tử được đảm bảo bởi thực tế là nó được trả về bởi getElementsByClassNamephương thức?
Thủy nhiệt

Thật không may, sự tồn tại không thực sự được đảm bảo theo như tôi biết, nhưng tôi không biết chi tiết về nó. Tôi mới trải nghiệm một số giá trị lạ hoặc không xác định một lần và tôi đặt kiểm tra ở đó mà không cần điều tra thêm. Vì vậy, đây là một chút hack.
csjpeter

Nó nên làdocument.getElementsByClassName(...
Công nhân

21

bạn chỉ có thể sử dụng element.remove()


13
element.remove()JavaScript không hợp lệ và chỉ hoạt động trong một số trình duyệt nhất định như Chrome .
Zaz

4
Josh, nó là javascript hợp lệ, ngoại trừ chỉ có Firefox và Chrome triển khai nó (Xem MDN)
Tim Nguyen

10
Điểm xấu của tôi element.remove() JavaScript hợp lệ với DOM4 và hoạt động trong tất cả các trình duyệt hiện đại, ngoại trừ Internet Explorer.
Zaz

24
Hoạt động tốt trên FireFox và Chrome. Ai quan tâm đến IE
Arun Sharma

13
những người có việc làm quan tâm đến IE!
sqram

18

Các ChildNode.remove()phương pháp loại bỏ các đối tượng từ cây nó thuộc về.

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

Đây là một câu đố cho thấy làm thế nào bạn có thể gọi document.getElementById('my-id').remove()

https://jsfiddle.net/52kp584L/

**

Không cần phải mở rộng NodeList. Nó đã được thực hiện rồi.

**


2
Lưu ý, điều này không được hỗ trợ trong bất kỳ phiên bản IE nào!
Macroman

1
Nếu bạn vẫn đang phát triển cho IE tôi cảm thấy rất tiếc cho bạn.
Alex Fallenstedt

Bạn không phát triển cho IE? Tôi cảm thấy rất tiếc cho khách hàng hoặc khách hàng của bạn.
Macroman

13

Bạn có thể loại bỏ trực tiếp phần tử đó bằng remove()phương thức DOM.

đây là một ví dụ:

let subsWrapper = document.getElementById("element_id");
subsWrapper.remove();
//OR directly.
document.getElementById("element_id").remove();


7

Trước tiên tôi phải vào nút cha có vẻ hơi kỳ lạ, có lý do gì JavaScript hoạt động như thế này không?

Tên hàm là removeChild(), và làm thế nào có thể loại bỏ đứa trẻ khi không có cha mẹ? :)

Mặt khác, bạn không phải luôn gọi nó như bạn đã thể hiện. element.parentNodechỉ là một người trợ giúp để có được nút cha của nút đã cho. Nếu bạn đã biết nút cha, bạn có thể sử dụng nó như thế này:

Ví dụ:

// Removing a specified element when knowing its parent node
var d = document.getElementById("top");
var d_nested = document.getElementById("nested");
var throwawayNode = d.removeChild(d_nested);

https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild

================================================== =======

Để thêm một cái gì đó nữa:

Một số câu trả lời đã chỉ ra rằng thay vì sử dụng parentNode.removeChild(child);, bạn có thể sử dụng elem.remove();. Nhưng như tôi đã nhận thấy, có một sự khác biệt giữa hai chức năng và nó không được đề cập trong các câu trả lời đó.

Nếu bạn sử dụng removeChild(), nó sẽ trả về một tham chiếu đến nút bị loại bỏ.

var removedChild = element.parentNode.removeChild(element); 
console.log(removedChild); //will print the removed child.

Nhưng nếu bạn sử dụng elem.remove();, nó sẽ không trả lại cho bạn tài liệu tham khảo.

var el = document.getElementById('Example');
var removedChild = el.remove(); //undefined

https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove

Hành vi này có thể được quan sát trong Chrome và FF. Tôi tin rằng nó đáng chú ý :)

Hy vọng câu trả lời của tôi thêm một số giá trị cho câu hỏi và sẽ hữu ích !!


6

Các hàm sử dụng ele.parentNode.removeChild (ele) sẽ không hoạt động đối với các phần tử bạn đã tạo nhưng chưa được chèn vào HTML. Các thư viện như jQuery và Prototype khôn ngoan sử dụng một phương thức như sau để tránh giới hạn đó.

_limbo = document.createElement('div');
function deleteElement(ele){
    _limbo.appendChild(ele);
    _limbo.removeChild(ele);
}

Tôi nghĩ rằng JavaScript hoạt động như vậy bởi vì các nhà thiết kế ban đầu của DOM giữ cha mẹ / con cái và điều hướng trước đó / tiếp theo là ưu tiên cao hơn so với các sửa đổi DHTML rất phổ biến hiện nay. Có thể đọc từ một <input type = 'text'> và viết cho người khác theo vị trí tương đối trong DOM là hữu ích vào giữa những năm 90, thời điểm mà việc tạo động của toàn bộ biểu mẫu HTML hoặc các thành phần GUI tương tác chỉ là một sự lấp lánh mắt của một số nhà phát triển.


3

Trước tiên tôi phải vào nút cha có vẻ hơi kỳ lạ, có lý do gì JavaScript hoạt động như thế này không?

IMHO: Lý do cho điều này giống như tôi đã thấy trong các môi trường khác: Bạn đang thực hiện một hành động dựa trên "liên kết" của bạn với một cái gì đó. Bạn không thể xóa nó trong khi bạn liên kết với nó.

Giống như chặt một cành cây. Ngồi ở phía gần cây nhất trong khi cắt hoặc kết quả sẽ là ... không may (mặc dù buồn cười).


2

Cái này thực sự đến từ FireFox ... lần đầu tiên, IE đã đi trước gói và cho phép loại bỏ một phần tử trực tiếp.

Đây chỉ là giả định của tôi, nhưng tôi tin rằng lý do bạn phải loại bỏ một đứa trẻ thông qua cha mẹ là do vấn đề với cách FireFox xử lý tài liệu tham khảo.

Nếu bạn gọi một đối tượng để trực tiếp cam kết hari-kari, thì ngay sau khi nó chết, bạn vẫn đang giữ tham chiếu đó cho nó. Điều này có khả năng tạo ra một số lỗi khó chịu ... chẳng hạn như không xóa nó, xóa nó nhưng giữ các tham chiếu đến nó có vẻ hợp lệ hoặc đơn giản là rò rỉ bộ nhớ.

Tôi tin rằng khi họ nhận ra vấn đề, công việc xung quanh là loại bỏ một phần tử thông qua phần tử mẹ của nó bởi vì khi phần tử đó không còn nữa, bây giờ bạn chỉ cần giữ một tham chiếu đến phần cha mẹ. Điều này sẽ ngăn chặn tất cả sự khó chịu đó, và (ví dụ, nếu đóng một nút cây theo nút) sẽ "nén" khá độc đáo.

Đây có thể là một lỗi dễ sửa, nhưng cũng như nhiều thứ khác trong lập trình web, việc phát hành có lẽ đã vội vàng, dẫn đến điều này ... và đến khi phiên bản tiếp theo xuất hiện, đủ người sử dụng nó để thay đổi điều này sẽ dẫn đến để phá vỡ một loạt các mã.

Một lần nữa, tất cả điều này chỉ đơn giản là phỏng đoán của tôi.

Tuy nhiên, tôi mong đến ngày khi lập trình web cuối cùng cũng được dọn dẹp toàn bộ mùa xuân, tất cả những điều bình dị kỳ lạ này được dọn sạch, và mọi người bắt đầu chơi theo cùng một quy tắc.

Có lẽ một ngày sau khi người hầu robot của tôi kiện tôi đòi lại tiền lương.


10
Tôi nghi ngờ rằng Firefox chịu trách nhiệm cho việc này. removeChildlà một phương thức của giao diện DOM Cấp 1Node .
Felix Kling

0

Theo những gì tôi hiểu, việc loại bỏ một nút trực tiếp không hoạt động trong Firefox, chỉ có Internet Explorer. Vì vậy, để hỗ trợ Firefox, bạn phải tìm đến cha mẹ để loại bỏ nó.

Tham chiếu: http://chiragrdarji.wordpress.com/2007/03/16/remondelete-element-from-page-USE-javascript- Work-in-firefoxieopera /


6
Điều đó không thực sự trả lời câu hỏi của tôi và trang bạn liên kết để cung cấp giải pháp tồi tệ hơn của tôi.
Zaz

0
// http://javascript.crockford.com/memory/leak.html
// cleans dom element to prevent memory leaks
function domPurge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        for (i = a.length - 1; i >= 0; i -= 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            domPurge(d.childNodes[i]);
       }
    }
}

function domRemove(id) {
    var elem = document.getElementById(id);
    domPurge(elem);
    return elem.parentNode.removeChild(elem);
}

-3

Đây là chức năng tốt nhất để xóa phần tử không có lỗi tập lệnh:

function Remove(EId)
{
    return(EObj=document.getElementById(EId))?EObj.parentNode.removeChild(EObj):false;
}

Lưu ý đến EObj=document.getElementById(EId).

Đây là MỘT dấu bằng không ==.

nếu phần tử EIdtồn tại thì hàm sẽ loại bỏ nó, nếu không thì nó trả về false, không error.


4
Tạo một biến toàn cục.
bjb568

1
Đây cũng là phiên bản tồi tệ nhất của một câu trả lời khác , nhưng trễ 2 năm.
Emile Bergeron
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.