What are the common mistakes to avoid when coding javascript for Internet Explorer?
I'm about to start coding a new, javascript-heavy website, but before I start I'd like to minimize my debugging time in Internet Explorer by knowing beforehan开发者_如何学JAVAd what the quirks are. I'm not planning to worry too much about IE6.
What are the common mistakes/differences to avoid in javascript code that work fine in other browsers, but break in Internet Explorer?
If you assign an event handler directly via javascript, event
will not be provided automatically.
myElement.onclick = function(e) {
alert(typeof e); // undefined
}
the workaround is to pull window.event
.
myElement.onclick = function(e) {
e = e || window.event;
alert(typeof e); // this is ok now
}
if you're an event handler directly on the element, you can provide the event
reference manually.
<input type="text" onclick="myMethod(event);"></input>
this is cross browser and is fine, if you have to go that route.
using attachEvent
to set an event handler provides the event
object as a parameter to the method automatically.
Here's a subtle one: if your site has multiple frames (or iframes), and you've got Javascript code communicating between frames sometimes, IE (6 and 7, not so sure about 8 and 9) is very picky about the "lineage" of Javascript objects, even ones without any DOM references. What that means is that if you communicate a Javascript object of almost any type (strings and numbers are usually OK, but even Date instances have caused me problems in the past) from one frame to another, if at some point later the source frame is updated with a new page, the destination page will get an exception if it tries to mess with that communicated object. Firefox was pretty mellow about that sort of thing, but when IE garbage collects the old page, it thereafter does not like references to the Javascript objects that page created.
IE (8 and lower, not sure about 9) cannot handle accessing characters in strings like arrays, as in:
var str = 'abc';
var c = str[2];
alert(c)
In most browsers this will alert 'c', but IE alerts 'undefined'. For cross-browser reasons one should rather use the charAt function:
var str = 'abc';
var c = str.charAt(2);
alert(c)
This will alert 'c' in IE as well.
Another small difference is that of the trailing comma in objects and arrays. This is valid in most browsers, but raises errors in IE:
ar = [1,2,3,]
and also
ob = {name:'janet', surname:'walker',}
which can be quite irritating if you're not aware of it. Both these problems are probably something I run in frequently because I'm used to python, but it's still worth looking out for.
Concatenate strings with +
var str="";
for (var i = 0; i < max; ++i) {
str += somefunction(i);
}
On MSIE it can take several minutes. I once did a test where Opera an Firefox where finished after a few seconds, but MSIE hadn't finished after 20 MINUTES!
However, if using an array, MSIE was fast:
var str = [];
for (var i = 0; i < max; ++i) {
str.push( somefunction(i));
}
str = str.join("");
Sorry, but can't find the post I made about it right now.
IE's JS engine, prior to IE9, is slow. Really, really slow. Hundreds to thousands of times slower than the Mozilla and Webkit implementations.
This shows up in the minimum resolution of animation timers, the time to complete sorts and (as @some pointed out) bogus string concatenation, and anywhere else where your site's performance is bounded by the speed of the JS engine itself.
Be aware of how Internet Explorer handles dom tree parsing and navigation, one in particular, that also exists when parsing httpObjects in general :
xmlNode.textContent
does not return anything in internet explorerxmlNode.firstChild.nodeValue
or something that returns the node value must be used
Internet Explorer.
Ok more seriously, the trailing comma answer in another answer is good. Using a framework can help, but its not a catch-all. You are going to have to deal with cross browser issues. So make sure you test in all versions you care about.
IE does not support custom events, only DOM events (yes even in 9 beta).
The most common mistake while writing a site that has to support IE is to forget to test in every version.
You need to make sure all your code works in IE6 (if you plan to support it), IE7, IE8, and IE8-in-IE7-mode. And also IE9 (which is now in beta).
There area few shortcuts to testing multiple versions of IE, but be aware that they don't always give exactly the same results as what real users will see; the only way to be sure is to actually test it in real versions of IE, no matter how painful that is.
Watch out for little differences like the way iframe borders are handled (How to Remove an IFrame border in Javascript).
I guess the internet-explorer tag should give you lots of good examples.
If you are trying to measure how long time something takes, you should know that the resolution of the time is only about 15ms in IE where it is 1ms in FF, Chrome and Opera.
You can test this yourself with this code:
var end,start = new Date().getTime(); //Gets number of milliseconds since epoch
while( (end = new Date().getTime() ) === start); //Wait for the time to change
alert(end-start); // Shows 1 in FF, Chrome and Opera, but 15 or 16 in MSIE
It has been like this for ages and still applies to MSIE8 but isn't common knowledge. lincolnk linked to a blog post by John Resig from 12th Nov 2008 in a comment above. I can't help that I smile a little when I read that, because I have known it for years, back when Netscape was the common browser.
When I think about it, I have a very faint memory that Netscape from the beginning had low resolution too, possibly by reading the system time that was updated 18.2 times per second, but later changed it so it gives time with 1ms resolution. However, since this should have happened about 15 years ago I'm not sure if it's correct and I'm not going to try to prove it.
For readability I'm using getTime above instead of an unary operator
IE 7/8 fails to understand console.log/dir unless console window opened. This can easily break your JS if you leave any in the prod environment. Always have
if(window.console)
console.log('Hello World')
Use a framework like jQuery or Prototype and you will not need to worry about it.
EDIT:
I should clarify. You will have a lot less to worry about. Such as:
- ActiveXObject vs XMLHttpRequest
- attachEvent vs addEventListener
List item-
精彩评论