Let\'s say that I define an element
$foo = $(\'#foo\');
and then I call
$foo.remove()
from some event. My
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]).
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;
}
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).
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