How do I check whether a jQuery element is in the DOM?
Let's say that I define an element开发者_运维问答
$foo = $('#foo');
and then I call
$foo.remove()
from some event. My question is, how do I check whether $foo has been removed from the DOM or not? I've found that $foo.is(':hidden')
works, but that would of course also return true if I merely called $foo.hide()
.
Like this:
if (!jQuery.contains(document, $foo[0])) {
//Element is detached
}
This will still work if one of the element's parents was removed (in which case the element itself will still have a parent).
How about doing this:
$element.parents('html').length > 0
I just realized an answer as I was typing my question: Call
$foo.parent()
If $f00
has been removed from the DOM, then $foo.parent().length === 0
. Otherwise, its length will be at least 1.
[Edit: This is not entirely correct, because a removed element can still have a parent; for instance, if you remove a <ul>
, each of its child <li>
s will still have a parent. Use SLaks' answer instead.
Since I'm unable to respond as a comment (too low karma I guess), here's a full reply. The fastest way is easily to unroll the jQuery check for browser support and to shave the constant factors to minimum.
As seen also here - http://jsperf.com/jquery-element-in-dom/28 - the code would look like this:
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);
This is semantically equivalent to jQuery.contains(document.documentElement, elt[0]).
Probably the most performative way is:
document.contains(node); // boolean
This also works with jQuery:
document.contains($element[0]); // var $element = $("#some-element")
document.contains(this[0]); // in contexts like $.each(), `this` is the jQ object
Source from MDN
Note:
- Internet Explorer only supports
contains()
for elements.
instead of iterating parents you can just get the bounding rect which is all zeros when the element is detached from dom
function isInDOM(element) {
var rect=element.getBoundingClientRect();
return (rect.top || rect.bottom || rect.height || rect.width)?true:false;
}
if you want to handle the edge case of a zero width and height element at zero top and zero left you can double check by iterating parents till the document.body
I liked this approach. No jQuery and no DOM search. First find the top parent (ancestor). Then see if that is the documentElement.
function ancestor(HTMLobj){
while(HTMLobj.parentElement){HTMLobj=HTMLobj.parentElement}
return HTMLobj;
}
function inTheDOM(obj){
return ancestor(obj)===document.documentElement;
}
Agree with Perro's comment. It can also be done like this:
$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;
};
Why not just: if( $('#foo').length === 0)...
?
if($foo.nodeType ){ element is node type}
精彩评论