如何检查 jQuery 元素是否在 DOM 中?

假设我定义了一个元素

$foo = $('#foo');

然后我打电话

$foo.remove()

来自某个事件。我的问题是,如何检查 $foo 是否已从 DOM 中删除?我发现 $foo.is(':hidden')可以工作,但是如果我只调用 $foo.hide(),那么当然也会返回 true。

60400 次浏览

我在打字的时候突然想到了一个答案: 打电话

$foo.parent()

如果从 DOM 中删除了 $f00,则为 $foo.parent().length === 0。否则,其长度至少为1。

编辑: 这并不完全正确,因为一个被移除的元素仍然可以有一个父元素; 例如,如果你移除一个 <ul>,它的每个子 <li>仍然有一个父元素。用 SLaks 的答案代替。

像这样:

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

如果删除了元素的父元素之一(在这种情况下,元素本身仍然有一个父元素) ,那么它仍然可以工作。

不如这样:

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

同意佩罗的评论,也可以这样做:

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

由于我无法回应作为一个评论(太低业力我猜) ,这里有一个完整的答复。最快的方法是轻松展开 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.include (document.documentElement,ELT [0])。

为什么不只是: 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;
};

我喜欢这个方法。没有 jQuery 和 DOM 搜索。首先找到顶端的父(祖先)。然后查看这是否是 documentElement。

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

也许最具表现力的方式是:

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

注:

不需要迭代父元素,你只需要得到边界 rect 当元素从 dom 分离出来的时候,边界 rect 都是零

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

如果您想处理宽度和高度为零、顶部为零、左边为零的元素的边缘情况,那么可以通过迭代父元素直到 document.body 来进行双重检查