Как проверить, находится ли элемент jQuery в DOM?

предположим, что я определяю элемент

$foo = $('#foo');

и

$foo.remove()

из какого-то события. Мой вопрос в том, как проверить, был ли $foo удален из DOM или нет? Я нашел это $foo.is(':hidden') работает, но это, конечно, также вернет true, если я просто позвоню $foo.hide().

11 ответов


такой:

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

Это будет работать, если один из родителей элемент был удален (в этом случае сам элемент будет родителем).


Как насчет этого:

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

Я только что понял ответ, когда я набирал свой вопрос: Call

$foo.parent()

если $f00 был удален из DOM, то $foo.parent().length === 0. В противном случае его длина будет не менее 1.

[Edit: это не совсем правильно, потому что удаленный элемент все еще может иметь родителя; например, если вы удалите <ul>, каждый из своих детей <li>s по-прежнему будет иметь родителя. Вместо этого используйте ответ Слакса.


поскольку я не могу ответить как комментарий (слишком низкая карма, я думаю), вот полный ответ. Самый быстрый способ-легко развернуть проверку jQuery для поддержки браузера и свести постоянные факторы к минимуму.

Как видно также здесь -http://jsperf.com/jquery-element-in-dom/28 - код будет выглядеть так:

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

это семантически эквивалентно jQuery.содержит(документ.documentElement, elt[0]).


Мне понравился этот подход. Нет jQuery и нет поиска DOM. Сначала найдите верхнего родителя (предка). Затем посмотрите, является ли это documentElement.

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

согласен с комментарием Перро. Это также можно сделать следующим образом:

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

почему не просто: if( $('#foo').length === 0)... ?


if($foo.nodeType ){ element is node type}

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

вероятно, самый перформативный способ:

document.contains(node); // boolean

Это также работает с jQuery:

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

источник MDN

Примечание:


вместо итерации родителей вы можете просто получить ограничивающую прямую, которая является всеми нулями, когда элемент отделен от dom

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

Если вы хотите обработать крайний случай нулевого элемента ширины и высоты в нулевом верхнем и нулевом левом углу, вы можете дважды проверить, повторяя родителей до документа.тело