Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Wait for an element to exist on the page with jQuery
var waitForEl = function(selector, callback) {
if (jQuery(selector).length) {
callback();
} else {
setTimeout(function() {
waitForEl(selector, callback);
}, 100);
}
};
waitForEl(selector, function() {
// work the magic
});
@trananhmanh89

This comment has been minimized.

Copy link

commented Aug 3, 2016

Awesome!

@scr4bble

This comment has been minimized.

Copy link

commented Mar 6, 2017

👍 nice and simple

@yngrdyn

This comment has been minimized.

Copy link

commented Mar 21, 2017

Thank you!

@luhaoming

This comment has been minimized.

Copy link

commented Jun 1, 2017

thank you~

@smithbrianscott

This comment has been minimized.

Copy link

commented Jun 19, 2017

Exactly what I needed! Thanks

@QwertyZW

This comment has been minimized.

Copy link

commented Oct 6, 2017

That looks like a stackbomb

function waitForEl(selector, callback){
    var poller1 = setInterval(function(){
        $jObject = jQuery(selector);
        if($jObject.length < 1){
            return;
        }
        clearInterval(poller1);
        callback($jObject)
    },100);
}
@mordini

This comment has been minimized.

Copy link

commented Jan 22, 2018

I agree about the stackbomb, because I made something similar and found out the hard way :D

Here's a version that will only iterate by a limited amount, though it isn't clearing the interval like QwertyZW's is...

var waitForEl = function(selector, callback, count) {
  if (jQuery(selector).length) {
    callback();
  } else {
    setTimeout(function() {
      if(!count) {
        count=0;
      }
      count++;
      console.log("count: " + count);
      if(count<10) {
        waitForEl(selector,callback,count);
      } else {return;}
    }, 100);
  }
};

var selector = $("#Whatevs");

waitForEl(selector, function() {
  // work the magic
  console.log("yay");
});
@laromicas

This comment has been minimized.

Copy link

commented Jan 27, 2018

I made this one, I read is better for modern browsers.

var waitForEl = function(selector, callback) {
	if (!jQuery(selector).size()) {
		setTimeout(function() {
			window.requestAnimationFrame(function(){ waitForEl(selector, callback) });
		}, 100);
	}else {
		callback();
	}
};
@dagda1

This comment has been minimized.

Copy link

commented Feb 13, 2018

Here is a version that uses promises:

export const wait = (selector) => {
  return new Promise((resolve, reject) => {
    const waitForEl = (selector, count = 0) => {
      const el = jQuery(selector);

      if (!!el) {
        resolve(el);
      } else {
        setTimeout(() => {
          count++;

          if (count < 10) {
            waitForEl(selector, count);
          } else {
            reject();
          }
        }, 100);
      }
    };

    waitForEl(selector);
  });
};
@superhero1

This comment has been minimized.

Copy link

commented Mar 1, 2018

@dagda1 how do i use that? Can you give me an example please?

@jcoyle37

This comment has been minimized.

Copy link

commented Mar 29, 2018

@mordini In your example, var selector = $("#Whatevs"); should be var selector = "#Whatevs"; ...otherwise great function, thank you!

@talent3310

This comment has been minimized.

Copy link

commented May 23, 2018

Awesome!

@skiza

This comment has been minimized.

Copy link

commented May 24, 2018

I use this with max times optional ^^. thank you

  var waitForEl = function (selector, callback, maxTimes = false) {
      if (jQuery(selector).length) {
        callback();
      } else {
        if (maxTimes === false || maxTimes > 0) {
          (maxTimes != false) && maxTimes-- ;
          setTimeout(function () {
            waitForEl(selector, callback, maxTimes);
          }, 100);
        }
      }
    };
@nebaughman

This comment has been minimized.

Copy link

commented Jul 5, 2018

Thanks for the gist. Below is a mashup of @QwertyZW's version (using setInterval) and maxtries (ala @skiza), plus interval param:

/**
 * Wait for the specified element to appear in the DOM. When the element appears,
 * provide it to the callback.
 *
 * @param selector a jQuery selector (eg, 'div.container img')
 * @param callback function that takes selected element (null if timeout)
 * @param maxtries number of times to try (return null after maxtries, false to disable, if 0 will still try once)
 * @param interval ms wait between each try
 */
waitForEl(selector, callback, maxtries = false, interval = 100) {
  const poller = setInterval(() => {
    const el = jQuery(selector)
    const retry = maxtries === false || maxtries-- > 0
    if (retry && el.length < 1) return // will try again
    clearInterval(poller)
    callback(el || null)
  }, interval)
}
@jthomas077

This comment has been minimized.

Copy link

commented Aug 30, 2018

To elaborate on these methods of waiting for an element to become available in the DOM, jQuery actually has a couple built-in ways to achieve this - both are promised based:

https://api.jquery.com/jquery.when/

$.when($('.something')).then((self) => { console.log(self); });

https://api.jquery.com/promise/

$('.something').promise().done((self) => { console.log(self); });

Also, considering JavaScript isn't a statically type language, coalescing two types in a single variable can potentially produce unstable results, bloat logic and increase overhead in evaluating expressions, thus by keeping maxTimes / maxtries as a number, you can effectively omit checking for a false value in which would actually also never contain a true value.

Otherwise, some great variations of achieving this... albeit, only if it were a decade ago lol.

Happy coding! :)

@shpoont

This comment has been minimized.

Copy link

commented Dec 22, 2018

@jthomas077
$.when() will immediately resolve anything that is not a Deferred or a Promise.
.promise() will work with animations or custom .queue(), neither of which can be easily used to watch for new element creation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.