Làm cách nào để kiểm tra xem một phần tử jQuery có trong DOM không?


147

Hãy nói rằng tôi xác định một yếu tố

$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 đã bị xóa khỏi DOM hay chưa? Tôi đã tìm thấy nó $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 $foo.hide().

Câu trả lời:


238

Như thế này:

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

Điều này sẽ vẫn hoạt động nếu một trong các phần tử cha mẹ của phần tử bị xóa (trong trường hợp đó phần tử vẫn sẽ có phần tử cha mẹ).


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

48
@PerroAzul: Tôi tìm thấy một sự thay thế nhanh hơn nhiều : jsperf.com/jquery-element-in-dom/2
SLaks

3
Hiệu suất là mối quan tâm trước mắt của tôi với phương pháp này, cảm ơn vì đã liên kết các điểm chuẩn @SLaks. Vì vậy, có vẻ như $.contains(document.documentElement, $foo.get(0))là cách nhanh nhất.
Christof

10
Có một cách DOM thuần túy để làm điều này, về mặt cú pháp dễ đọc hơn và tôi tưởng tượng rất giống nhau về hiệu suất:document.contains($foo[0])
Joel Cross

3
Tất cả điều này nói về hiệu suất ...? Các điểm chuẩn cho thấy một phương pháp mất 15 micro giây và một phương pháp khác mất 0,15 micro giây. Nhưng thực sự, ai quan tâm - bạn sẽ không nhận thấy bất kỳ sự khác biệt nào trừ khi bạn làm điều đó hàng trăm ngàn lần. Và tất cả có thể thay đổi nếu jQuery hoặc công cụ JavaScript được tối ưu hóa. Hãy sử dụng bất kỳ phương thức nào đọc tốt hơn cho bạn và bất cứ ai phải duy trì mã của bạn trong tương lai.
James


5

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

$foo.parent()

Nếu $f00đã bị xóa khỏi DOM, thì $foo.parent().length === 0. Nếu không, chiều dài của nó sẽ ít nhất là 1.

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


2
... trừ khi nút bị loại bỏ không phải là con duy nhất
Álvaro González

@ Álvaro - Tại sao điều đó lại quan trọng?
dùng113716

@patrick: Tôi có bỏ lỡ điều gì không? Bạn có thể đảm bảo điều gì nếu $ foo.parent (). Độ dài lớn hơn 0?
Álvaro González

@ Álvaro - OP đang thử nghiệm để đảm bảo $foođã bị xóa khỏi DOM. Nếu nó được xóa thành công, nó sẽ không còn phần tử cha. Do đó, $foo.parent().length === 0có nghĩa là việc loại bỏ đã thành công.
dùng113716

1
$ foo.closest ("cơ thể") sẽ là một sửa chữa cho kỹ thuật này
georgephillips

4

Vì tôi không thể trả lời như một bình luận (tôi đoán là nghiệp quá thấp), đây là một câu trả lời đầy đủ. Cách nhanh nhất là dễ dàng hủy đăng ký kiểm tra jQuery để hỗ trợ trình duyệt và cạo các yếu tố không đổi đến mức tối thiểu.

Như đã thấy ở đâ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);

Điều này tương đương về mặt ngữ nghĩa với jQuery.contains (document.documentEuity, elt [0]).


3

Có lẽ cách hiệu quả nhất là:

document.contains(node); // boolean

Điều này cũng hoạt động 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

Ghi chú:


Làm thế nào có ai nhìn vào câu trả lời này chưa? Câu trả lời tuyệt vời +1 (Tôi đã gửi một phiên bản, cảm ơn)
Guilherme Nascimento

1

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

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

1

thay vì lặp đi lặp lại cha mẹ, bạn chỉ có thể nhận được trực tràng giới hạn là tất cả các số không khi phần tử được tách ra khỏi dom

function isInDOM(element) {
    var rect=element.getBoundingClientRect();
    return (rect.top || rect.bottom || rect.height || rect.width)?true:false;
}

nếu bạn muốn xử lý trường hợp cạnh của phần tử chiều rộng và chiều cao bằng 0 ở đỉnh 0 và 0 trái, bạn có thể kiểm tra lại bằng cách lặp lại cha mẹ cho đến tài liệu.


Mặc dù đoạn mã này có thể giải quyết vấn đề, nhưng nó không giải thích tại sao hoặc làm thế nào để trả lời câu hỏi. Vui lòng bao gồm một lời giải thích cho mã của bạn , vì điều đó thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. Flaggers / người đánh giá: Đối với các câu trả lời chỉ có mã như câu trả lời này, downvote, đừng xóa!
Luca Kiebel

Không phải điều này cũng nhận ra các yếu tố ẩn là "không có trong DOM" sao? ví dụ: một phần tử display: nonekhông có ràng buộcRect
Philipp

0

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

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

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

-1

Tại sao không chỉ : if( $('#foo').length === 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 có trong DOM không", không phải "làm thế nào để kiểm tra xem một phần tử có khớp với chuỗi bộ chọn đã cho có trong DOM hay không."
Trevor Burnham

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

@Matt $ foo có thể là một thành phần trong bộ nhớ tách ra khỏi DOM và có thể cho tôi một thành phần 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ó thể muốn kiểm tra xem nó có trong DOM hay không. Ai đó làm việc trong những thứ như vậy rõ ràng biết cách truy vấn DOM.
TJ ngày

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.