假设我定义了一个元素
$foo = $('#foo');
然后我调用
$foo.remove()
从某些事件中,我的问题是如何检查$ foo是否已从DOM中删除?我发现$ foo.is(':hidden')可以工作,但那当然也会返回true,如果我仅仅调用了$ foo.hide()。假设我定义了一个元素
$foo = $('#foo');
然后我调用
$foo.remove()
从某些事件中,我的问题是如何检查$ foo是否已从DOM中删除?我发现$ foo.is(':hidden')可以工作,但那当然也会返回true,如果我仅仅调用了$ foo.hide()。像这样:
if (!jQuery.contains(document, $foo[0])) {
//Element is detached
}
如果元素的一个父级被删除,此方法仍将起作用(在这种情况下,元素本身仍然具有一个父级)。
怎么样做这件事:
$element.parents('html').length > 0
可能最有效的方法是:
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
注意:
我在输入问题时意识到了一个答案:调用
$foo.parent()
$f00
已从DOM中删除,则$foo.parent().length === 0
。否则,它的长度将至少为1。
[编辑:这不是完全正确的,因为已删除的元素仍然可以有父级;例如,如果您删除一个<ul>
,那么它的每个子<li>
仍将具有父级。请改用SLaks的答案。
$foo
已从DOM中删除。如果成功删除,它将不再具有父元素。因此,$foo.parent().length === 0
表示删除成功。 - user113716d=$('<vader>'); c=$('<luke>').appendTo(d);
在这种情况下,c.parent()
是 vader
,但是两者都不在 DOM 中。 - oriadam因为我无法以评论的形式回应(我猜因为我的声望太低了),所以在这里提供完整的回复。最快的方法是轻松解开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.contains(document.documentElement, elt[0])。
不需要遍历父元素,只需获取边界矩形即可。当元素从 DOM 中分离时,边界矩形的值为零。
function isInDOM(element) {
var rect=element.getBoundingClientRect();
return (rect.top || rect.bottom || rect.height || rect.width)?true:false;
}
如果您想处理宽度和高度为零、顶部和左侧位置均为零的元素的边缘情况,可以通过迭代父元素直到document.body来进行双重检查。
display:none
的元素也没有boundingRect。 - Philippfunction ancestor(HTMLobj){
while(HTMLobj.parentElement){HTMLobj=HTMLobj.parentElement}
return HTMLobj;
}
function inTheDOM(obj){
return ancestor(obj)===document.documentElement;
}
同意Perro的评论。也可以这样做:
$foo.parents().last().is(document.documentElement);
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;
};
if( $('#foo').length === 0)...
? 这样更简洁明了。$foo
的选择器进行重新查询,并检查重新查询是否匹配任何元素,似乎是解决问题的可行方法。由于jQuery和浏览器优化某些选择器(例如通过ID),因此它甚至可能比其他解决方案更快。 - Matt
$foo.closest(document.documentElement)
会更快(参考 http://jsperf.com/jquery-element-in-dom)。 - urraka$.contains(document.documentElement, $foo.get(0))
是最快的方法。 - Christofdocument.contains($foo[0])
。 - Joel Cross