-1

Right now whenever I use that code on Chrome Console, it'll click the button as long as it's already there but what I'm trying to get it to do is to do the same thing when the button doesn't exist but exists at a random time.

(function (){
    document.getElementsByClassName("buttonContent-18Mz6_")[0].click();
})();
treachery
  • 11
  • 1
  • please elaborate your question it's hard to realize what do you want??. when then function trigger what are you doing?? let me guess you are alerting something, then use js interval function to do that job as you want it in a random time. – ANIK ISLAM SHOJIB Aug 24 '19 at 14:59
  • Define random? It is not clear, is this based on a timer? Event? – Jackal Aug 24 '19 at 15:06

2 Answers2

2

To have a performant solution and a modern one, you can use MutationObserver for this task :

/** 
 * @const target the target element to watch for new added elements.
 * @const observer the mutation observer.
 **/
const target = document.body,
  observer = new MutationObserver((mutationsList, observer) => {
    /** loop through the mutations **/
    for (let mutation of mutationsList) {
      /** wer're watching only for the changes on the child list of the target  **/
      /** see if the added (also that may include notifications about removed child nodes) child is the wanted button **/
      const btn = target.querySelector('button.buttonContent-18Mz6_');
      /** if yes just click it and disconnect the observer **/
      btn && (btn.click, observer.disconnect());
      /** exit the callback **/
      if(btn) return;
    }
  });

/** start the observer **/
observer.observe(target, {
  childList: true,
  /** we only watch for the child list changes only **/
  attributes: false,
  subtree: false
});

/** for testing, add that button after 5 seconds to see the result **/
window.setTimeout(() => {
  const btn = document.createElement('button');
  btn.className = 'buttonContent-18Mz6_';
  btn.textContent = 'button'
  btn.addEventListener('click', console.log('button clicked !'));
  target.appendChild(btn);
}, 5000);
buttonContent-18Mz6_
<div id="mutation-target">
  <p>wait for about 5 seconds...</p>
</div>
ThS
  • 4,597
  • 2
  • 15
  • 27
  • I'm getting this error when trying it: Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'. – treachery Aug 24 '19 at 16:10
  • can you show me the code you're using, especially the element you send for `observe` method as it's first argument. – ThS Aug 24 '19 at 16:12
  • I'm trying to run it through Google Chrome console without changing anything. – treachery Aug 24 '19 at 16:22
  • I was looking for something like Andrei posted but to loop constantly and click the button everytime it appears rather than only once. – treachery Aug 24 '19 at 16:30
  • @treachery then replace `target = document.getElementById('mutation-target')` with `target = document.body` for example to watch for change in all the page. See updated code above. – ThS Aug 24 '19 at 16:56
  • Cheers for this clever approach, I'm learning new stuff every day. I think it can be a more performant solution than mine, but if the document suffers plenty of mutations it could become slower than `setInterval` itself. But for most, static sites, this shouldn't be the case. – Andrei Aug 24 '19 at 17:19
  • @Andrei one mutation object should suffice ! – ThS Aug 24 '19 at 19:09
1

If you're expecting your button to appear at some point in the future, you may employ setInterval in order to attempt to click the button until it finally appears like this:

(function (){
    const tryClickingElement = () => {
        const element = document.getElementsByClassName("buttonContent-18Mz6_")[0];

        if(element) {
            element.click();
            clearInterval(myInterval);
        }
    }

    const myInterval = setInterval(tryClickingElement, 1000);
})();
Andrei
  • 400
  • 2
  • 6
  • This works perfectly, how do I make it loop so that it clicks the button everytime it appears rather than it only clicking when the button appears once? – treachery Aug 24 '19 at 16:08
  • this is a poor approach as it'll consume plenty of the `CPU` ressources. – ThS Aug 24 '19 at 16:13
  • Is there a way to change "buttonContent-18Mz6_" to certain text as that'll allow it to constantly click the same button rather than the classname. – treachery Aug 24 '19 at 17:11
  • Regarding changing the class' name it would be difficult for me to tell. Perhaps you can make use of sibling elements, the parent node, a child node etc that doesn't change. You ought to be able to figure out a smart selector for that. – Andrei Aug 24 '19 at 17:16
  • The button says "Join" and it never changes, is there something I can replace I tried getElementsByText but that doesn't seem to work. – treachery Aug 24 '19 at 18:00
  • To be precise, what I'm trying to do is whenever the button appears it clicks it even if there's another button under it rather than clicking the same button above it. – treachery Aug 24 '19 at 18:03
  • Would [this](https://stackoverflow.com/questions/3813294/how-to-get-element-by-innertext) help you out? – Andrei Aug 24 '19 at 20:05