views:

235

answers:

12

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 beforehand 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?

+4  A: 

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.

hvgotcodes
Heh. I don't normally +1 answers like these, because they are not all that helpful, but...dang it if I LOL'd. (IE has been the source of a lot of stress on a project I have been working on recently.)
JasCav
Easy money... :P
annakata
This original answer (an oneliner "Internet Explorer") has however killed the entire question which was at its own not so bad.
BalusC
i edited with my limited knowledge...
hvgotcodes
A: 

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-

Josiah Ruddell
I dont know if this is really true...
hvgotcodes
+1 for this. The libraries were specifically designed so you don't have to worry about all the compatibilities and differences between browser implementations. Good advice for @Herman.
JasCav
@hvgotgotcodes - it's the reason jquery exists, so it really should be...
annakata
Not true. You still need to worry about object creation, commas at the end of arrays or not, brackets after newlines... things like that.
Herman
@annakata -- jquery failed for me with xml parsing. See http://stackoverflow.com/questions/3513919/jquery-and-xml-issue
hvgotcodes
I'm on team jQuery but as alternative consider dojo don't consider Prototype at all.
Thomas
should be != is :)
annakata
jQuery doesn't parse XML.
Tim Down
@Thomas - Why not `prototypejs`? What do you know that [these guys](http://www.apple.com/) don't know?
patrick dw
@tim, you can certainly use jquery to get at data in xml. Which might or might not be the same as 'parsing' the xml, but semantics aside, it had real problems.
hvgotcodes
@hvgotcodes: jQuery pretends XML is HTML by assigning an XML string as the `innerHTML` of an element. This is not reliable: see this question http://stackoverflow.com/questions/2908899/jquery-wont-parse-xml-with-nodes-called-option and also the jQuery docs: http://api.jquery.com/jQuery/#jQuery2
Tim Down
You can use jQuery to get at data in an XML DOM (from `XMLHttpRequest#responseXML`). You can't feed jQuery a stringful of XML markup and expect it to make a workable XML DOM out of it, because all it's doing is writing your string to `innerHTML`. It's weird that so many people seem to think this should work.
bobince
@patrick dw http://en.wikipedia.org/wiki/Prototype_JavaScript_Framework#Problems
Thomas
@tim fair enough. thanx for clarifying that for me.
hvgotcodes
@bobince -- my use case was the former.
hvgotcodes
This doesn't answer the question.
notJim
+2  A: 

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 explorer
  • xmlNode.firstChild.nodeValue or something that returns the node value must be used

-

Gepsens
+5  A: 

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.

Pointy
+1  A: 

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.

Pedro
+7  A: 

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.

lincolnk
+1  A: 

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.

Spudley
That's true - but often Internet Explorer's errors are so kind as to inform you that there's an "Error on line 0", and then you sort of have to either install a debugger for every version or know beforehand which kind of differences between IE and other browsers can cause this.
Herman
+3  A: 

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.

some
+1  A: 

IE does not support custom events, only DOM events (yes even in 9 beta).

AutoSponge
+4  A: 

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.

DDaviesBrackett
the timer resolution issue seems to be a matter of internal implementation rather than the js engine just being slow. http://ejohn.org/blog/accuracy-of-javascript-time/
lincolnk
point taken - but that's still a JS-engine implementation decision that contributes to IE8 feeling sluggish.
DDaviesBrackett
+2  A: 

IE (7 and lower, not sure about 8 or 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.

Herman
That is non-standard behaviour anyway, so IE is well within its rights not to support it.
Tim Down
Don't work in MSIE8
some
A: 

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

some