Michael Mikowski
Michael Mikowski

Reputation: 1279

check if cached jquery object is still in DOM

Does anyone know how to tell if a cached jQuery object has gone stale, e.g. is no longer in the DOM? For example:

var $cached_elem = $('.the_button');

// .. and then later

$cached_elem.text('updating...');

I have recently encountered the situation where the $cached_elem is removed from the DOM due to some other event. So what I would like to do:

if ( $cache_elem.isStillInDOM() ){
  // now do time consuming stuff with $cached_elem in DOM 
}

Before anyone offers, I have already employed this, which is a fair analog for what I'm trying to do:

if ( $cached_elem.is(':visible') === true ){ ... }

However, this is not really the same thing and could fail in some cases.

So can anyone think of a simple way to check directly if a cached jQuery object is "stale"? I may be forced to write a plugin if not ...

Upvotes: 16

Views: 6553

Answers (4)

Steve Greatrex
Steve Greatrex

Reputation: 15999

if($elem.closest('body').length > 0) seems like it could do the trick.

$(function() {
    var $button = $(".the_button");
    alert (isStale($button));
    $button.remove();
    alert (isStale($button));
});
    
function isStale($elem)
{
    return $elem.closest("body").length > 0;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <span class="the_button">Hello World</span>
</div>

Edit: Updated in response to Yi Jiang's comment so that it will return correctly if its parent element is removed

Edit 2: Updated in response to lonesomeday's comment - changed parents() to 'closest()` for performance improvement

Upvotes: 26

ryenus
ryenus

Reputation: 17391

In a slightly variant case, one can directly compare the native DOM element wrapped by the jQuery object $cached_elem.

$cached_elem[0] === $($cached_elem.selector)[0]

Besides checking if the $cached_elem is still in DOM, this can tell you if it's still the original DOM element, rather than a re-created one with same attributes after certain/partial page refresh.

Upvotes: 0

Thomas Higginbotham
Thomas Higginbotham

Reputation: 1792

The native document.contains() method should be faster than jQuery to determine if a cached jQuery element exists in the DOM.

if (document.contains($cached_elem[0])) {
    // Element is still in the DOM
}

Upvotes: 9

Jimmy
Jimmy

Reputation: 37081

If the selector hasn't changed, just reinitialize it:

var $cached_elem = $('.the_button');
// code that might remove some elements of $cached_elem
$cached_elem = $('.the_button');

If you want to avoid duplicating the selector string, use the selector property of the original jQuery object:

var $cached_elem = $('.the_button');
// code that might remove some elements of $cached_elem
$cached_elem = $($cached_elem.selector);
if ($cached_elem.length) {
  // element still exists
}

Upvotes: 0

Related Questions