5

Let's say I got a DOM element, as a param of an event, for example click.

$(document).click(function() {
    myElement = $(this);
});

How can I check later that myElement is still in the DOM? I can't use .length or any other things like that because it still refer to the saved element and the state of the DOM at this moment, right?

8 Answers8

5

You can check element parent:

function isInDom(obj) {
    var root = obj.parents('html')[0] 
    return !!(root && root === document.documentElement);
}


if(isInDom(myElement)) {
     ...
}

Here's working fiddle: http://jsfiddle.net/vnxhQ/7/

Inferpse
  • 4,135
  • 1
  • 31
  • 39
  • 1
    this tests whether the element **had** parents when it was stored, it has nothing to do with whether the element is still in the DOM. – jbabey Oct 08 '12 at 16:59
  • `myElement` needs to be a jQuery object wrapping the element, though.. but yeah, I don't buy it that this has anything to do when it was stored, either. – JayC Oct 08 '12 at 17:13
  • ah... but when was the DOM bject wrapped with jQuery...? – JayC Oct 08 '12 at 17:14
  • @Inferpse you're right, i tested it out in a [fiddle](http://jsfiddle.net/jbabey/P28Bq/), +1 – jbabey Oct 08 '12 at 17:17
  • @Inferpse it will not let me remove my downvote unless you edit your answer, make a fake edit and i will switch it to an upvote. thanks for teaching me something! – jbabey Oct 08 '12 at 17:18
  • 2
    An element may have an parent body-element without being a part of a document: http://jsfiddle.net/doktormolle/vnxhQ/1/ – Dr.Molle Oct 08 '12 at 17:33
  • Ah... better! Please add that to your post. – JayC Oct 08 '12 at 18:06
5

You're probably looking for Node.isConnected.

aryzing
  • 4,982
  • 7
  • 39
  • 42
2

The only reliable way I see so far is to check if the element is inside document.getElementsByTagName('*')

function isInDoc(element)
{
  var elements=document.getElementsByTagName(element.tagName);
  for(var i=0;i<elements.length;++i)
  {
    if(elements[i]===element)return true;
  }
  return false;
}

Demo: http://jsfiddle.net/doktormolle/hX8eN/


<edit>

Node.contains() seems to be supported by all major browsers, so I would finally suggest this:

if(document.documentElement.contains(myElement))

Demo: http://jsfiddle.net/doktormolle/LZUx3/

Dr.Molle
  • 116,463
  • 16
  • 195
  • 201
  • Ugh.... really? That's a lot of tags. Maybe you could combine Inferpse's answer with yours to 1. test to see if the element desends from a body tag. 2. test to see whether *that* element's body tag is the document's body tag. – JayC Oct 08 '12 at 17:38
  • (or can documents have more than one body tag??) – JayC Oct 08 '12 at 17:39
  • See my answer for clarification on what I meant. – JayC Oct 08 '12 at 17:58
  • I see what you mean. But I couldn't imagine that there is no native and easy method. `Node.contains()` looks fine to me. – Dr.Molle Oct 08 '12 at 19:19
  • Nice! But this method is supported by Firefox 9+ ? – Inferpse Oct 08 '12 at 19:33
0

In order to test if an element still exists in the DOM, you need to crawl the DOM again:

// store it in some shared scope
var myElement;
$(document).click(function() {
    myElement = $(this);
});

// sometime later...
if ($('#' + myElement.attr('id')).length > 0) {
    // it still exists
} else {
    // it no longer exists
}

Your clicked elements must all have ids for this to work, though. A class or any other selector could be used instead.

Edit: see this question for ideas on how to get a unique selector for any given DOM element.

Community
  • 1
  • 1
jbabey
  • 45,965
  • 12
  • 71
  • 94
0

This is assuming you would have the id of possible 'clickable' elements set

var idRef;
$(document).on('click', function() {
    idRef = this.id;    
});

later..

var exists = document.getElementById(idRef).length > 0;
st3inn
  • 1,556
  • 9
  • 17
0

You can the undocumented .selector property of a jQuery object to see if an element is still in the DOM, on the condition that it uses a unique ID. ​Obvious

http://jsfiddle.net/mblase75/CC2Vn/

$two = $('#two');
console.log($($two.selector).length); // 1
$two.remove();
console.log($($two.selector).length); // 0

See this question for more about how to get the selector of a jQuery object, which may or may not uniquely describe the DOM element(s) it contains.

Community
  • 1
  • 1
Blazemonger
  • 90,923
  • 26
  • 142
  • 180
0

Just to add something to the fray:

This is really Inferpse's answer slightly tweaked for Dr.Molle's corner case of creating another body element that might house the element removed from the general DOM tree (or, of course, maybe the element was never in the DOM in the first place.) Like Inferspe's answer, it takes a jQuery wrapped object, not the element itself.

function isInDom(jqobj) {
    var someBody = jqobj.parents('body');
    return someBody.length > 0 && someBody.get(0) === document.body;
}
​

I must admit I'm having trouble figuring out how I might try to break that.

Edit: Oh yeah... jsFiddle: http://jsfiddle.net/vnxhQ/5/

Edit II: of course, if we aren't talking about link or script elements (anything that might go into the head, not the body, I guess that might work fine :-/

JayC
  • 7,053
  • 2
  • 25
  • 41
0

Perhaps a better way of implementing Inferpse's function is by extending jQuery:

jQuery.fn.extend({
    isInDom: function() {
        var root = this.eq(0).parents('html')[0];
        return !!(root && root === document.documentElement);
    }
})

Usage:

$("div").isInDom() //returns true if your dom contains a div
$("<div />").isInDom() //returns false
$().isInDom() //returns false