1

I am trying to run a content script (chrome extension) on a page. I managed to work jQuery, and I am trying to select an element document.ready().

However, as the page is a single-page-application, everything gets loaded dynamically, and it doesn't catch the element.

I believe I can achieve it with using setTimeout approach, however that doesn't sound right.

What is the right way of waiting for the element to be present, and when present get the element or run some code?


Edit: In order to simplify the problem, here is an example:

<body>
   <div id="parent">
      <button class="a b c">...</button>
   </div>
</body>

Here, only body tag is created without any children, and then all the children get loaded into the body node dynamically as they are using Single-Page-Application approach (React to be specific).

MutationObserverAPI works as suggested in the comments, however it pulls all the changes and I couldn't figure out how to go through each MutationRecord object and detect if '.a.b.c' class exists or not. Is there a way to only observe and wait for the '.a.b.c' classed item exists, and when it does, get this element + triggering function.

This is the snippet I used for observing whole mutations:

MutationObserver = window.MutationObserver;

var observer = new MutationObserver(function(mutations, observer) {
    console.log(mutations);
});

observer.observe(document, {
    subtree: true,
    attributes: true,
    childList: true,
    characterData: true,
    attributeOldValue: true,
    characterDataOldValue: true
});

So where there is console.log, I simply want to observe only the element with the related class name.

senty
  • 12,385
  • 28
  • 130
  • 260
  • What Framework are you using, there are several callbacks based on the framework.? – Crisoforo Gaspar May 12 '17 at 22:57
  • 2
    The modern method is MutationObserver API, see also [Is there a JavaScript/jQuery DOM change listener?](//stackoverflow.com/q/2844565) – wOxxOm May 12 '17 at 22:58
  • @wOxxOm I checked [this answer](http://stackoverflow.com/a/11546242/4705339) however it doesn't seem to work on initial load. What I am trying to achieve is like: there is a ` – senty May 12 '17 at 23:56
  • You can wrap the whole script DOMContentLoaded and refer to the necessary function from there. Check [teyit.link extension](https://github.com/haraldur12/teyitlink-extension/blob/master/popup.js) – Ozan May 13 '17 at 00:04
  • @Ozan I couldn't figure out completely how I should combine these two. The scenario is I am going to a website (using React). There will be a button with `'.a.b.c'` classes that will be created dynamically. As @wOxxOm suggested, I could track every change using MutitionObserver approach, but looks pretty complex detecting one single element in all these changes. Can you please suggest a snippet in the answer part? I think this [Fiddle](https://jsfiddle.net/oc4de6nn/1) will be enough for replicating the problem. How can I detect when button with these classes gets created? – senty May 13 '17 at 00:21
  • and get the created button element created, too* - so that i can use it with `$(el)` – senty May 13 '17 at 00:45
  • @senty that's the best example that i could think of. Check [this fiddle](https://jsfiddle.net/oc4de6nn/8/) out. – Ozan May 13 '17 at 06:17
  • To conclude the question, I used MutationObserver API as @wOxxOm suggested, took a bit to understand at first but it works like charm in the end. Thanks ^^ (Specifically [this answer](http://stackoverflow.com/a/11546242/4705339)) – senty May 14 '17 at 04:47
  • Possible duplicate of [How to wait until an element exists?](https://stackoverflow.com/questions/5525071/how-to-wait-until-an-element-exists) – brasofilo Jun 14 '18 at 05:16
  • And another good candidate for dupe: [Is there a JavaScript/jQuery DOM change listener?](https://stackoverflow.com/q/2844565/1287812) – brasofilo Jun 14 '18 at 05:17

0 Answers0