Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scripts loading out of order in Chrome

I have an external script followed by an inline script at the bottom of my <body>. It looks like the inline script is running before the external script, which isn't supposed to happen, according to this answer:

If you aren't dynamically loading scripts or marking them as defer or async, then scripts are loaded in the order encountered in the page. It doesn't matter whether it's an external script or an inline script - they are executed in the order they are encountered in the page. Inline scripts that come after external scripts have are held until all external scripts that came before them have loaded and run.

Src: https://stackoverflow.com/a/8996894/114855

This is my code:

  <script src="https://checkout.stripe.com/checkout.js"></script>
  <script>
  var handler = StripeCheckout.configure({
    key: 'pk_live_HhFqemZFyEUJVorFzYvjUK2j',
    token: function(res) {
      $('#pay_token').val(res.id);
      $('#pay_email').val(res.email)
      $('#pay_amount').val(parseFloat($("#amount").val())*100);
      $('#pay_description').val($("#description").val());
      $('#pay_real').submit();
    }
  });

  /* .. */
  </script>

</body>

Console is showing that StripeCheckout is not defined (which the external script should define)

Console

This makes sense, since the network tab shows that my external request is still pending. But I'm not sure why the browser didn't wait for checkout.js to be fetched:

Network

like image 595
Colin Avatar asked Sep 29 '22 05:09

Colin


2 Answers

The comments to both answers in the quoted question indicate that the accepted answer is not backed by a standards reference (applicable to all commonly encountered browser versions) and indeed may not be true for all browsers, all of the time.

I can confirm that behavior. But there are hints on our feedback pages, that it might only work when test.php is cached. Do you know any spec/reference links about this?

This answer is incorrect. It is not always the case that "dynamically added scripts are executed as soon as they are appended to the document". Sometimes this is true (e.g. for old versions of Firefox), but usually it is not. The execution order, as mentioned in jfriend00's answer, is not determinate

To be completely safe, wait until the DOM is fully rendered before running your script.

like image 133
Eric J. Avatar answered Oct 24 '22 23:10

Eric J.


Ahha - I've figured it out!

This is part of a rails application running TurboLinks.

TurboLinks dynamically changes the body content instead of creating a new request every time you click a link. This means my script tags are being inserted dynamically, and the guarantee that they're run in order is lost.

Since TurboLinks does not re-evaluate script tags on every request, I think the easiest/best solution here is to include StripeCheckout on every page of my app (not just the one's it's needed on), within the <head>

I also think TurboLinks can resolve this by finding a way to run the scripts in order. I plan to followup with an issue on their github, and will update here accordingly.

like image 40
Colin Avatar answered Oct 24 '22 22:10

Colin