IE9 js load order and JQuery

This seems like an easy problem to solve, but it's kickin my ass.

The following simple example produces an error in IE9. I've used IE9's developer page to monitor network loading and it looks like IE is loading and executing the body's script before the included javascript is loaded/evaluated.

I've tried all the various tricks found via searching for answers including adding <meta charset="UTF-8" /> and <meta http-equiv="x-ua-compatible" content="IE8"/>

<html>
<head>
  <title>Demo of IE suckiness</title>
  <script type='text/javascript' 
      src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'></script>
  </head>
  <body>
This works in every browser but not IE9. IE gives the error:
<pre>
Line: 9
Error: The value of the property '$' is null or undefined, not a Function object
</pre>

<script type="text/javascript" defer="defer">
$(document).ready(function(){
  alert("Must not be IE");
});
</script>
</body>
</html>

I have a work-around. Move the ready script to <body onload="ready()">, but I can't believe this is broken for IE9, I must be doing something wrong and just can't see it.

Answers


I had a similar problem. I fixed it by resetting all my IE9 settings. I think by cranking up security or privacy it can break jquery loading from an external page.


As far as I could find out, IE9 only fires $.load() when the whole document (including all images & related stuff) has been loaded. Terrible but true! My workaround for this:

            var docReady = {
                actions:new Array(),
                flag:0,
                time:0,
                period:10,
                trigger:function() {this.flag=1},
                checkHandle:0,
                check:function() {
                    this.time+=this.period;
                    if(this.flag) {
                        clearInterval(this.checkHandle);
                        for(i in this.actions) {this.actions[i]();}
                    }
                },
                watch:function() {
                    this.checkHandle = setInterval(function() {docReady.check();},this.period);
                },
                action:function(f) {
                    this.actions.push(f);
                }

            };

            docReady.watch();

A dirty one indeed but it's working; now whenever you see fit, you can call docReady.trigger() and you should do it at least at the end of the page. Also, you can call it as body onload. It's guaranteed that the functions you've added with docReady.action() will only run once: when the first trigger() happens.


Have you tried to leave out defer="defer"?


I had the same problem and solved it by NOT using Google's hosted jQuery and hosting it locally.


Need Your Help

Encoding issues with Spring and Freemarker

java spring encoding jetty freemarker

I'm working on a project using Freemarker and Spring running on Jetty. It will involve displaying characters from many different countries so I'm trying to set the encoding to UTF-8. However, no ...

Multiple CSS styles on a html button

html css

I am trying to make a button for a message system to show an orange dot if there's a new message. However, i can't quite get it working. Is it possible?