0

I am loading jQuery in this way:

  function require(url, cb = new Function) {
    var s = document.createElement('script');
    s.src = url;
    // s.async=true; 
    // ^^^^^^^^^^^^ This is already removed, but the problem still existed.
    s.onload = cb;
    document.head.appendChild(s);
  }
  require(jquery_cdn_url, function(){
    try {
      alert($);
    } catch (e) {
      ga('send', 'pageview', e);
    }
  });

The error in the catch block is not happening all the time. But for some visitors (very small chance) because I tracked this by sending the information to Google Analytics.

In a previous version of this question, the script had the async attribute. However in the real project, I removed it, and the error still comes up.

Why is this happening? Is there any way to avoid this?

Some further thoughts:

  • The Google Analytics code was also loaded this way, so if the onload function doesn't work on some user agents, the ga() should also be sending nothing to Google.
  • I think of a way to avoid this: in the try ... catch block, to reload the failed case with a query like "xxx.html?load=sync". Then I do some detection on the server side, if there is a load=sync query, then I output a code with sync JavaScript tags inline. This sounds like a possible workaround but not perfect because it would require another reload (a lot more wasted network requests) and some server-side programming work amount.
AGamePlayer
  • 7,404
  • 19
  • 62
  • 119

3 Answers3

2

You're not saying which browsers the problem appears in, but support for the onload attribute for script tags across browsers seems to be spotty.

This could be causing the problems you're seeing - check the user agent strings to see whether the browser versions match.

Apparently the correct approach in older IE versions is to use onreadystatechange. Here is a writeup demonstrating how it's done.

Another detail to bear in mind is that the src attribute should be set after the onload attribute to guarantee that the onload handler is actually fired. It doesn't look like this could be the cause of your problem, though: if this goes wrong, the handler would not be fired at all.

Community
  • 1
  • 1
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • This seems to be the possible situation. I will do more tests on this. But if the user is using an older IE, the things in `onload` would never be executed. I did catch the error in the onload callback. And the Google Analytics report was sent inside that callback too. – AGamePlayer Dec 07 '16 at 12:21
  • @AwQiruiGuo I can't find any clear information on what older versions of IE actually *do* - whether the onload handler is never fired there, or fired right away without waiting for the script to load. If it's the latter, this could be the cause of your problem; if the former, then it has to be something else – Pekka Dec 07 '16 at 12:22
  • Well. It's possible. Thanks very much for you Pekka! Your links did get me a lot of ideas. I think maybe I can use more ways to improve the onload feature. – AGamePlayer Dec 07 '16 at 12:29
0

I've made a fiddle and it seems to work. I think the solution is to put the code in an onload event. Also you might be a cache clearing problem, refer to this question too.

window.onload = function() {
  function require(url, cb = new Function) {
    var s = document.createElement('script');
    s.src = url;
    s.async = true;
    s.onload = cb;
    document.head.appendChild(s);
  }
  require('https://code.jquery.com/jquery-2.2.4.min.js', function(){
    alert($); //ReferenceError: $ is not defined
  });
};
Community
  • 1
  • 1
Ionut Necula
  • 11,107
  • 4
  • 45
  • 69
  • It's not happening all the time. It happens in a very small chance and I have to trace that with a Google Analytics setup. I currently got 2 examples. And I did trace the User Agent. One is Linux and the other is Windows NT. – AGamePlayer Dec 07 '16 at 12:05
-2

The CDN url is loaded into the script tag added by your require function, BUT the CDN url will take dome time to load the js file from network. It will first make a fetch request and then will get the response back containing the file contents, only then is the jquery fully loaded and you can access $. Though this depends on your internet speed too. Sometimes you will get the CDN js content sooner and maybe sometimes it may take long.

Sanchit
  • 541
  • 2
  • 18
  • `the CDN url will take dome time to load the js file from network` But that's why he's using the `onload` event, no? – Pekka Dec 07 '16 at 12:03
  • `s.onload` will only check if the script tag is loaded in the DOM. NOT the CDN url being loaded. – Sanchit Dec 07 '16 at 12:05
  • 1
    Do you have a source for that? What I can see online seems to be saying differently – Pekka Dec 07 '16 at 12:07