5

I'm creating an external widget that uses jQuery and rather than have the user include it separately I'd like to check to see if it's loaded and load it dynamically if it's not.

Problem is I need to wait until it's loaded to execute the rest of the script, which requires event handlers that IE and FF/Chrome handle differently.

If I do this, it works fine in IE8:

<div id="test">
<p>This is a test.</p>
</div>

<script>
if (typeof jQuery == 'undefined') {
    s = document.createElement("script");
    s.src = "//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";
    if (s.addEventListener) {
        s.addEventListener("load", runScript, false);
    } else if (s.readyState) {
        s.onreadystatechange = runScript;
    }

} else {
    runScript();
}

function runScript() {
    document.getElementsByTagName('head')[0].appendChild(s);
    $('#test').css('font-size', '50px');

}
</script>

But that doesn't work in Chrome. However if I append the script earlier, it works in Chrome but not IE:

<div id="test">
<p>This is a test.</p>
</div>

<script>
if (typeof jQuery == 'undefined') {
    s = document.createElement("script");
    s.src = "//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";
    document.getElementsByTagName('head')[0].appendChild(s);
    if (s.addEventListener) {
        s.addEventListener("load", runScript, false);
    } else if (s.readyState) {
        s.onreadystatechange = runScript;
    }

} else {
    runScript();
}

function runScript() {

    $('#test').css('font-size', '50px');

}
</script>

Any ideas on how to dynamically load jQuery with event handlers that works both in IE and Chrome?

EDIT: Changed appendChild target from test to head.

OrdinaryHuman
  • 621
  • 11
  • 19
  • duplicate of http://stackoverflow.com/questions/1828237/check-if-jquery-has-been-loaded-then-load-it-if-false – jeremy Dec 26 '12 at 17:59
  • require.js could help you with that – ama2 Dec 26 '12 at 18:06
  • You're saying "when jQuery loads, append jQuery to some random element", that does'nt work, as you can't append the script when it loads, you have to append the script first, **then** do something when it loads, and you should probably append it to the `head`, not `test`, and you don't even have an element with a `test` tag, it's a div with a `test` ID ? – adeneo Dec 26 '12 at 18:09
  • @Nile I wouldn't say it's a duplicate of http://stackoverflow.com/questions/1828237/check-if-jquery-has-been-loaded-then-load-it-if-false -- that asks how to check if jQuery has been loaded. You can see I've already got that syntax in my examples, I'm asking about event handler compatibility across browsers. – OrdinaryHuman Dec 26 '12 at 19:56
  • @adeneo Agreed but appendChild prior to the event handler only seems to work in Chrome/FF, it does not work in IE8. Strangely only adding it after the event handler does it work in IE8. – OrdinaryHuman Dec 26 '12 at 19:57

1 Answers1

1

In the first code you are appending the script in the function you are calling when it is complete!

And what element is test?

document.getElementsByTagName('test')[0].appendChild(s);  <-- looking for element
<div id="test">  <-- test is an id

The code should look like

if (typeof jQuery == 'undefined') {
    var s = document.createElement("script");
    s.src = "//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";
    if (s.addEventListener) {
        s.addEventListener("load", runScript, false);
    } else if (s.readyState) {
        s.onreadystatechange = runScript;
    }
    document.getElementsByTagName('head')[0].appendChild(s);
} else {
    runScript();
}

function runScript() {
    $('#test').css('font-size', '50px');
}

Running example: http://jsfiddle.net/5986T/

epascarello
  • 204,599
  • 20
  • 195
  • 236
  • agreed #1 is wacky but try it in IE8 and it works, the second example, which makes more coding sense, works in Chrome but in IE while it works it also spits out a warning "Object expected" -- I assume it's executing before jQuery had been loaded? Updated my target from test to head for more clarity. – OrdinaryHuman Dec 26 '12 at 20:16
  • I'd also like to point out Microsoft provides this documentation: http://msdn.microsoft.com/en-us/library/ie/hh180173(v=vs.85).aspx But that didn't work for me in IE7/8 -- could be a settings issue on my end. – OrdinaryHuman Dec 26 '12 at 20:24
  • I added a running example that seems fine in IE7-IE9 for me. – epascarello Dec 26 '12 at 20:33
  • I tested on another config and it works. Thanks for your help. – OrdinaryHuman Dec 29 '12 at 17:28