'onload' handler for 'script' tag in internet explorer
Asked Answered
S

2

53

I've been using this function to attach onload handler to a script tag, it seems to be the recommended way over the internet.
Yet, it doesn't work in internet explorer, if page is loaded already (tested in ie 8). You can see that it works in normal browsers (fires alert when script is loaded).

Am I missing something?
Thank you

Suffix answered 30/1, 2011 at 21:50 Comment(4)
onload is not supported in IE8 and below. It works in IE9 Standards Mode.Chaco
@Chaco I'm not sure what you mean, window.attachEvent('onload', fn); has worked for me so far (IE 8). It's also mentioned on MSDNSuffix
@NikitaRybak I am also trying to implement a way to load jquery in a script (if not already loaded) and then call a function when it is loaded. There is no onload for scripts in ie unfortunately. Have you found a way to do that?Quinte
You might find this helpful while loading scripts with async=false. https://mcmap.net/q/57654/-javascript-dynamic-script-loading-ie-problemsApe
C
88

You should call jQuery.getScript, which does exactly what you're looking for.

EDIT: Here is the relevant source code from jQuery:

var head = document.getElementsByTagName("head")[0] || document.documentElement;
var script = document.createElement("script");
if ( s.scriptCharset ) {
    script.charset = s.scriptCharset;
}
script.src = s.url;

// Handle Script loading
    var done = false;

// Attach handlers for all browsers
script.onload = script.onreadystatechange = function() {
    if ( !done && (!this.readyState ||
            this.readyState === "loaded" || this.readyState === "complete") ) {
        done = true;
        jQuery.handleSuccess( s, xhr, status, data );
        jQuery.handleComplete( s, xhr, status, data );

        // Handle memory leak in IE
        script.onload = script.onreadystatechange = null;
        if ( head && script.parentNode ) {
            head.removeChild( script );
        }
    }
};

// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head.insertBefore( script, head.firstChild );
Caritacaritas answered 30/1, 2011 at 21:56 Comment(7)
Not really gonna work, because jquery isn't available initially: I have to load it like this. But I'll check the sources and see if it works in IE. +1 for the interesting reference, thanks!Suffix
A great answer, thanks man, you don't have to use jQuery to learn from this perfectly valid approach, and then write something similar. :)Osteomyelitis
I think that "jQuery.handleSuccess( s, xhr, status, data ); jQuery.handleComplete( s, xhr, status, data ); " is probably not neccesary, and will cause bugs if this is used verbatimBlennioid
Just a note to others that IE9+ supports both script.onload AND script.onreadystatechange (bit.ly/18gsqtw), so both events will be triggered (that's 2 calls), which is why "done" is needed. Good to remember if you need to wrap this up in a module to aid multiple script loads.Alphonse
you can find this same code here ready to use (without jQuery parts)Blowsy
Interesting that jQuery assigns the src attribute before inserting the script in the head. A Mozilla example importScript() does this in reverse order. One might assume that the sequence is important, but apparently not since both functions work.Anadem
Another problem is the cache of ie ,so a timestamp for the link may be neededBehind
P
12

I also had issues with script.onload = runFunction; in IE8.

I tried jQuery.getScript and it worked perfectly for my needs. The only downside is having to wait for jQuery to be loaded before adding in the script.

However, since my callback functions utilize jQuery very heavily anyway I find this an extremely acceptable and very minor downside since it creates a very easy to use, cross-browser solution.

Update:

Here is a way of doing it without using jQuery:

(a modified solution from: https://mcmap.net/q/57654/-javascript-dynamic-script-loading-ie-problems)

var url = 'http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js';
var headID = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.type='text/javascript';
script.src=url;

//for nonIE browsers
script.onload=function(){
        addVideo();
    }

 //for IE Browsers
 ieLoadBugFix(script, function(){
     addVideo();}
 );

function ieLoadBugFix(scriptElement, callback){
        if (scriptElement.readyState=='loaded' || scriptElement.readyState=='completed') {
             callback();
         }else {
             setTimeout(function() {ieLoadBugFix(scriptElement, callback); }, 100);
         }


 }

headID.appendChild(script);
Peristyle answered 15/3, 2013 at 16:38 Comment(2)
It looks like jQuery manages to work it out without polling. Try onreadystatechange instead of setting timeoutPittsburgh
The ieLoadBugFix function does the work really well. It have tested it. I am excited how stackoverflow has helped with a solution proposed 8 years back. It is amazingVarhol

© 2022 - 2024 — McMap. All rights reserved.