events - Executing javascript loaded via DOM insertion - Stack Overflow

I'm working on something that will add a widget to a customer's site, and I want to load my j

I'm working on something that will add a widget to a customer's site, and I want to load my js asynchronously so as not to block the customer's page loading. I've been reading a lot of threads about this, and have been trying to implement the pattern suggested here as my project is very similar:

The problem I have is the code in my dynamically-loaded javascript file just doesn't get executed. Sorry if this seems to be a duplicate question, but I've spent hours searching and trying slightly different techniques, and I've read numerous posts including these stackoverflow questions:

  • Load javascript async, then check DOM loaded before executing callback
  • Load jQuery in a js, then execute a script that depends on it
  • Loading scripts dynamically

but I'm still struggling to make this work, so I was hoping if I ask the question directly someone here might be able to help me out!

I've currently got the following as a really basic test; obviously there's a lot more going on in my real script, but I just need to understand what's happening here (or, in fact, what's not happening).

So in my code file "test.js" I simply have:

run_test = function () {
    alert('hello from test');
};

then on the page I have:

(function () {
     load_test = function () {
        var t = document.getElementsByTagName('script')[0];
        var s = document.createElement('script');
        s.type = 'text/javscript';
        s.async = true;
        s.src = 'test.js';

        s.onload = s.readystatechange = function () {
            if (run_test) run_test();

            s.onload = null;
            s.onreadystatechange = null;
        };

        t.parentNode.insertBefore(s, t);
    };

    load_test();
})();

I've already tried several variations on this - I've tried removing "s.async = true" just to see if it makes a difference, but it doesn't. I originally had the following instead of "load_test();", as suggested in the first post I mentioned:

window.attachEvent ? window.attachEvent('onload', load_test) : window.addEventListener('load', load_test, false);

but the result is always the same, I never see the message "hello from test". In fact I can even put alerts in the load_test function - if I put an alert just before the line "s.onload = s.readystatechange .." I see that message, but an alert within that onload function never appears. So it would appear that the dynamically added script's onload never fires.

BTW as an aside - may or may not be relevant, but I generally test in Firefox, and if I look at the html in firebug, I see the test.js script has been loaded, but if I expand that node I just see the message "Reload the page to get source for ...". Doesn't matter how many times I reload the page, I can't see the code. I have tried testing in other browsers with the same results.

Can't help feeling I'm missing something fundamental here; any help would be very much appreciated!

Pete


Thanks all for the input.

@zzzzBov, thanks for the example, although I'm not sure I pletely understand still - I thought that "onload" would fire once after the script finishes loading, in the same way as attaching code to the onload event of the page. My understanding of "onreadystatechange" was that it was just to catch the same thing in IE.

In response to your ments, the new script is inserted in the head of the page (with the insertBefore statement) right before the original script block (assuming the original script block is in the head, which it is).

With regard to the test.js path, I omitted the path just to simplify the example. My path to the script is definitely correct; I can see via firebug that the script is actually added (to the head).

My problem was that after the script loaded, it simply failed to run, but I think I was actually hitting some caching problems as I've since got this working using the pattern described in the first link I posted above (here it is again for good measure: /).

So my code is something like this:

(function () {
    var addscript = function () {
        var h = document.getElementsByTagName('head')[0],
            s = document.createElement('script');
        s.type = "text/javascript";
        s.async = true;
        s.src = "myscript.js";
        h.appendChild(s);
    };
    window.attachEvent ? window.attachEvent('onload', addscript) : 
        window.addEventListener('load', addscript, false);
})();

If you check the ments on that post, I think it's explained somewhere why it's a good idea to still include "s.async = true" even though in this case the script is attached to the window onload event.

My "real" main script does actually require jQuery, so I think my eventual solution will be to use something like this to load jQuery, then once I know that's loaded, let jQuery do the work of loading any other scripts I need.

Thanks again for the help.

Pete

I'm working on something that will add a widget to a customer's site, and I want to load my js asynchronously so as not to block the customer's page loading. I've been reading a lot of threads about this, and have been trying to implement the pattern suggested here as my project is very similar:

http://friendlybit./js/lazy-loading-asyncronous-javascript

The problem I have is the code in my dynamically-loaded javascript file just doesn't get executed. Sorry if this seems to be a duplicate question, but I've spent hours searching and trying slightly different techniques, and I've read numerous posts including these stackoverflow questions:

  • Load javascript async, then check DOM loaded before executing callback
  • Load jQuery in a js, then execute a script that depends on it
  • Loading scripts dynamically

but I'm still struggling to make this work, so I was hoping if I ask the question directly someone here might be able to help me out!

I've currently got the following as a really basic test; obviously there's a lot more going on in my real script, but I just need to understand what's happening here (or, in fact, what's not happening).

So in my code file "test.js" I simply have:

run_test = function () {
    alert('hello from test');
};

then on the page I have:

(function () {
     load_test = function () {
        var t = document.getElementsByTagName('script')[0];
        var s = document.createElement('script');
        s.type = 'text/javscript';
        s.async = true;
        s.src = 'test.js';

        s.onload = s.readystatechange = function () {
            if (run_test) run_test();

            s.onload = null;
            s.onreadystatechange = null;
        };

        t.parentNode.insertBefore(s, t);
    };

    load_test();
})();

I've already tried several variations on this - I've tried removing "s.async = true" just to see if it makes a difference, but it doesn't. I originally had the following instead of "load_test();", as suggested in the first post I mentioned:

window.attachEvent ? window.attachEvent('onload', load_test) : window.addEventListener('load', load_test, false);

but the result is always the same, I never see the message "hello from test". In fact I can even put alerts in the load_test function - if I put an alert just before the line "s.onload = s.readystatechange .." I see that message, but an alert within that onload function never appears. So it would appear that the dynamically added script's onload never fires.

BTW as an aside - may or may not be relevant, but I generally test in Firefox, and if I look at the html in firebug, I see the test.js script has been loaded, but if I expand that node I just see the message "Reload the page to get source for ...". Doesn't matter how many times I reload the page, I can't see the code. I have tried testing in other browsers with the same results.

Can't help feeling I'm missing something fundamental here; any help would be very much appreciated!

Pete


Thanks all for the input.

@zzzzBov, thanks for the example, although I'm not sure I pletely understand still - I thought that "onload" would fire once after the script finishes loading, in the same way as attaching code to the onload event of the page. My understanding of "onreadystatechange" was that it was just to catch the same thing in IE.

In response to your ments, the new script is inserted in the head of the page (with the insertBefore statement) right before the original script block (assuming the original script block is in the head, which it is).

With regard to the test.js path, I omitted the path just to simplify the example. My path to the script is definitely correct; I can see via firebug that the script is actually added (to the head).

My problem was that after the script loaded, it simply failed to run, but I think I was actually hitting some caching problems as I've since got this working using the pattern described in the first link I posted above (here it is again for good measure: http://friendlybit./js/lazy-loading-asyncronous-javascript/).

So my code is something like this:

(function () {
    var addscript = function () {
        var h = document.getElementsByTagName('head')[0],
            s = document.createElement('script');
        s.type = "text/javascript";
        s.async = true;
        s.src = "myscript.js";
        h.appendChild(s);
    };
    window.attachEvent ? window.attachEvent('onload', addscript) : 
        window.addEventListener('load', addscript, false);
})();

If you check the ments on that post, I think it's explained somewhere why it's a good idea to still include "s.async = true" even though in this case the script is attached to the window onload event.

My "real" main script does actually require jQuery, so I think my eventual solution will be to use something like this to load jQuery, then once I know that's loaded, let jQuery do the work of loading any other scripts I need.

Thanks again for the help.

Pete

Share Improve this question edited May 23, 2017 at 11:47 CommunityBot 11 silver badge asked Sep 24, 2011 at 17:41 PeteMPeteM 3433 silver badges10 bronze badges 4
  • You should declare "load_test" with var of course. Also, it should be "onreadystatechange". Also also, I'm not sure you'll reliably get those events in all browsers. – Pointy Commented Sep 24, 2011 at 17:51
  • While I realize that jQuery isn't necessary for many issues in JavaScript, this entire issue can be solved by jQuery(function($){ $.getScript('test.js', run_test);});. jQuery's great for normalizing events across browser so that you don't have to. – zzzzBov Commented Sep 24, 2011 at 18:03
  • Hi, thanks for the responses. @Pointy, yes I've added "var" in front of load_test, and "readystatechange" was just a typo. My understanding of the events is onreadystatechange will work for IE, and onload will work for other browsers? I've certainly seen this usage numerous times. – PeteM Commented Oct 2, 2011 at 10:21
  • @zzzzBov, ideally I would use jQuery for everything, but in this case I'm adding my script(s) to a customer site, so can't be sure jQuery will be referenced / loaded. – PeteM Commented Oct 2, 2011 at 10:24
Add a ment  | 

1 Answer 1

Reset to default 5

You've got a few issues with your script. Here's one that should work.

function loadScript(src, callback)
{
  var s, r;
  r = false;
  s = document.createElement('script');
  s.type = 'text/javascript';
  s.src = src;
  s.onload = s.onreadystatechange = function() {
    //console.log( this.readyState ); //unment this line to see which ready states are called.
    if ( !r && (!this.readyState || this.readyState == 'plete') )
    {
      r = true;
      callback();
    }
  };
  document.body.appendChild(s);
}

The issue with your load_test function is that it'll call run_test() before the new script has executed. Your script will remove the onload and onreadystatechange event callbacks at the first onreadystatechange event which is typically loading.

Also, async should be unnecessary, as the newly added script will be inserted at the end of the document.body wherever that may be. If you'd like to load the script after the rest of the page, then wait for the rest of the page to load (body.onload or document.onreadystatechange) before calling loadScript.

The biggest issue with your script sounds like test.js doesn't exist at the path it's being called. Make sure that adding <script type="text/javascript" src="test.js"></script> inline actually works.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745565224a4633353.html

相关推荐

  • events - Executing javascript loaded via DOM insertion - Stack Overflow

    I'm working on something that will add a widget to a customer's site, and I want to load my j

    5小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信