2010-06-21 67 views
131

Hãy nói rằng tôi xác định một yếu tốLàm cách nào để kiểm tra xem một phần tử jQuery có nằm trong DOM không?

$foo = $('#foo'); 

và sau đó tôi gọi

$foo.remove() 

từ một số sự kiện. Câu hỏi của tôi là, làm cách nào để kiểm tra xem $ foo có bị xóa khỏi DOM hay không? Tôi đã tìm thấy rằng $foo.is(':hidden') hoạt động, nhưng điều đó tất nhiên cũng sẽ trở lại đúng nếu tôi chỉ gọi là $foo.hide().

Trả lời

215

Như thế này:

if (!jQuery.contains(document, $foo[0])) { 
    //Element is detached 
} 

này sẽ vẫn làm việc nếu một trong cha mẹ của phần tử đã được gỡ bỏ (trong trường hợp các yếu tố bản thân vẫn sẽ có một mẹ).

+0

+1 đó là trơn tru :) –

+12

làm '$ foo.closest (document.documentElement)' là nhanh hơn (nếu có ai quan tâm http://jsperf.com/jquery-element-in-dom) – urraka

+47

@PerroAzul: Tôi tìm thấy một thay thế nhanh hơn _much_: http://jsperf.com/jquery-element-in-dom/2 – SLaks

4

Tôi chỉ nhận ra một câu trả lời khi tôi đang gõ câu hỏi của tôi: Gọi

$foo.parent() 

Nếu $f00 đã bị xóa khỏi DOM, sau đó $foo.parent().length === 0. Nếu không, độ dài của nó sẽ tối thiểu là 1.

[Chỉnh sửa: Điều này không hoàn toàn chính xác, vì phần tử đã xóa vẫn có thể có bố mẹ; ví dụ: nếu bạn xóa <ul>, mỗi đứa con của nó <li> s sẽ vẫn có cha mẹ. Sử dụng câu trả lời của SLaks để thay thế.

+1

... trừ khi nút loại bỏ không phải là một đứa con duy nhất –

+0

@ Álvaro - Tại sao vấn đề đó? – user113716

+0

@patrick: Tôi có nhớ điều gì đó không? Bạn có thể đảm bảo điều gì nếu $ foo.parent(). Chiều dài lớn hơn 0? –

21

Làm thế nào về việc này:

$element.parents('html').length > 0 
+0

Tôi nghĩ rằng điều này là nhanh hơn rất nhiều –

+13

Thực ra nó là chậm nhất: http://jsperf.com/jquery-element-in-dom/60 – suda

0

Đồng ý với bình luận Perro của. Nó cũng có thể được thực hiện như thế này:

$foo.parents().last().is(document.documentElement); 
4

Vì tôi không thể trả lời làm nhận xét (quá thấp nghiệp), đây là câu trả lời đầy đủ. Cách nhanh nhất là dễ dàng để unroll kiểm tra jQuery cho hỗ trợ trình duyệt và để cạo các yếu tố liên tục đến mức tối thiểu.

Như đã thấy cũng ở đây - http://jsperf.com/jquery-element-in-dom/28 - mã sẽ trông như thế này:

var isElementInDOM = (function($) { 
    var docElt = document.documentElement, find, 
     contains = docElt.contains ? 
     function(elt) { return docElt.contains(elt); } : 

     docElt.compareDocumentPosition ? 
      function(elt) { 
      return docElt.compareDocumentPosition(elt) & 16; 
      } : 
      ((find = function(elt) { 
       return elt && (elt == docElt || find(elt.parentNode)); 
      }), function(elt) { return find(elt); }); 

    return function(elt) { 
    return !!(elt && ((elt = elt.parent) == docElt || contains(elt))); 
    }; 
})(jQuery); 

Đây là ngữ nghĩa tương đương với jQuery.contains (document.documentElement, ELT [0]).

0

Tại sao không chỉ: if($('#foo').length === 0)...?

+0

@stevematdavies Câu hỏi là "làm thế nào để kiểm tra xem một phần tử trong một đối tượng jQuery đã cho nằm trong DOM ", không phải" cách kiểm tra xem một phần tử có khớp với chuỗi chọn nhất định có trong DOM hay không. " –

+0

@TrevorBurnham: trong tất cả sự công bằng, truy vấn lại bằng bộ chọn được sử dụng để tạo '$ foo' và kiểm tra xem truy vấn lại có khớp với bất kỳ phần tử nào hay không, dường như là giải pháp khả thi cho vấn đề trong nhiều trường hợp.Nó thậm chí có thể nhanh hơn * so với một số giải pháp khác vì cách jQuery và trình duyệt tối ưu hóa một số bộ chọn nhất định (chẳng hạn như bằng ID). – Matt

+0

@Matt $ foo có thể là một phần tử trong bộ nhớ tách ra khỏi DOM và có thể có một phần tử có bộ chọn phù hợp trong DOM. Những người đang tìm kiếm câu trả lời cho câu hỏi này có lẽ muốn kiểm tra xem nó có trong DOM hay không. Một người làm việc trong những thứ như thế rõ ràng là biết cách truy vấn DOM. –

0
if($foo.nodeType){ element is node type} 
0
jQuery.fn.isInDOM = function() { 
    if (this.length == 1) { 
     var element = this.get(0); 
     var rect = element.getBoundingClientRect(); 
     if (rect.top + rect.bottom + rect.width + rect.height + rect.left + rect.right == 0) 
     return false; 
     return true; 
    } 
    return false; 
}; 
0

tôi thích phương pháp này. Không có jQuery và không có tìm kiếm DOM. Đầu tiên tìm cha mẹ hàng đầu (tổ tiên). Sau đó xem nếu đó là documentElement.

function ancestor(HTMLobj){ 
    while(HTMLobj.parentElement){HTMLobj=HTMLobj.parentElement} 
    return HTMLobj; 
} 
function inTheDOM(obj){ 
    return ancestor(obj)===document.documentElement; 
} 
0

Có lẽ cách performative nhất là:

document.contains(node); // boolean 

này cũng làm việc với jQuery:

document.contains($element[0]); // var $element = $("#some-element") 
document.contains(this[0]); // in contexts like $.each(), `this` is the jQ object 

Nguồn từ MDN

Lưu ý:

+0

Có ai đã xem câu trả lời này chưa? Câu trả lời hay nhất +1 (Tôi sugested một ấn bản, cảm ơn) –

Các vấn đề liên quan