Search code examples
javascriptclicksettimeoutgreasemonkeytampermonkey

How to run one function right after another in JavaScript?


I'm automating a task on Paypal that involves clicking a couple buttons on a page in succession.

Basically, I need to click a radio button and then click a "next" button to advance to the following page. But I can't advance to the next page unless the radio button is clicked first.

I currently have the second function on a timer, but is there a way to start the second function after the first function finishes and the first radio button's pressed?

Here's my code:

// ==UserScript==
// @name     PayPal Transfer Radio
// @include  https://www.paypal.com/myaccount/money/balances/withdraw/balance/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @grant    GM_addStyle
// ==/UserScript==
    
$(function(){
  $('[id="BA-SMSNY4E48EHGC__ACH__STANDARD_FUNDSRadioBtn"]').click()
});

setTimeout(function(){
    $('[name="selectFiNext|standard"]').click();
}, 2000);

The setTimeout method works, as is, but it's not optimal.


Solution

  • setTimeout is the simplest, most reliable method. When patching pages you don't own, it's a great approach.

    If you want to click the next button as soon as it appears, decrease the timeout, and if the button doesn't exist yet, set a new timeout. There's also no need to rely on a big dependency like jQuery here:

    document.querySelector('[id="BA-SMSNY4E48EHGC__ACH__STANDARD_FUNDSRadioBtn"]').click();
    const clickNext = () => {
      const btn = document.querySelector('[name="selectFiNext|standard"]');
      if (btn) btn.click();
      else setTimeout(clickNext, 50);
    };
    setTimeout(clickNext, 50);
    

    If you really want to avoid polling, you can also use a MutationObserver on the parent of the button, but that gets significantly more complicated.

    If the button appears after a network request, another option that can work is to watch for when network requests complete, with ajaxComplete if the site is using jQuery, or by monkeypatching window.XMLHttpRequest.