I developed some javascript enhanced pages that run fine on recent Firefox and Safari. I missed to check in Internet Explorer, and now I find the pages don’t work on IE 6 and 7 (so far). The scripts are somehow not executed, the pages show as if javascript wasn’t there, although some javascript is executed. I am using own libraries with dom manipulation, from YUI 2 I use YUI-Loader and the XML-Http-Request, and on one page I use “psupload”, which depends on JQuery.
I am installing Microsoft Script Editor from Office XP and will now debug. I will also write specific tests now.
What are the typical failing points of IE? What direction I can keep my eyes open.
I found this page, which shows some differences. visit: Quirksmode
Can you from your experience name some typical things I should look for first?
I will also ask more questions here for specific tasks later, but for now I am interested in your experience why IE usually fails on scripts that run fine in Firefox
Edit: Thank you for all those great answers!
In the meantime I have adapted the whole code so that it also works with Internet Explorer. I integrated jQuery and built my own classes on top of it now. This was my basic mistake, that I did not build all my stuff on jQuery from the beginning. Now I have.
Also JSLint helped me a lot.
And many of the single issues from the different answers helped.
Please feel free to update this list if you see any errors/omissions etc.
Note: IE9 fixes many of the following issues, so a lot of this only applies to IE8 and below and to a certain extent IE9 in quirks mode. For example, IE9 supports SVG,
<canvas>,<audio>and<video>natively, however you must enable standards compliance mode for them to be available.##General:
Problems with partially loaded documents: It’s a good idea to add your JavaScript in a
window.onloador similar event as IE doesn’t support many operations in partially loaded documents.Differing attributes: In CSS, it’s
elm.style.styleFloatin IE vselm.style.cssFloatin Firefox. In<label>tags theforattribute is accessed withelm.htmlForin IE vselm.forin Firefox. Note thatforis reserved in IE soelm['for']is probably a better idea to stop IE from raising an exception.##Base JavaScript language:
Access characters in strings:
'string'[0]isn’t supported in IE as it’s not in the original JavaScript specifications. Use'string'.charAt(0)or'string'.split('')[0]noting that accessing items in arrays is significantly faster than usingcharAtwith strings in IE (though there’s some initial overhead whensplitis first called.)Commas before the end of objects: e.g.
{'foo': 'bar',}aren’t allowed in IE.##Element-specific issues:
Getting the
documentof an IFrame:IFrame.contentDocument(IE started supporting this from version 8.)IFrame.contentWindow.documentIFrame.contentWindowrefers to thewindowin both browsers.)Canvas: Versions of IE before IE9 don’t support the
<canvas>element. IE does support VML which is a similar technology however, and explorercanvas can provide an in-place wrapper for<canvas>elements for many operations. Be aware that IE8 in standards compliance mode is many times slower and has many more glitches than when in quirks mode when using VML.SVG: IE9 supports SVG natively. IE6-8 can support SVG, but only with external plugins with only some of those plugins supporting JavaScript manipulation.
<audio>and<video>: are only supported in IE9.Dynamically creating radio buttons: IE <8 has a bug which makes radio buttons created with
document.createElementuncheckable. See also How do you dynamically create a radio button in Javascript that works in all browsers? for a way to get around this.Embedded JavaScript in
<a href>tags andonbeforeunloadconflicts in IE: If there’s embedded JavaScript in thehrefpart of anatag (e.g.<a href="javascript: doStuff()">then IE will always show the message returned fromonbeforeunloadunless theonbeforeunloadhandler is removed beforehand. See also Ask for confirm when closing a tab.<script>tag event differences:onsuccessandonerroraren’t supported in IE and are replaced by an IE-specificonreadystatechangewhich is fired regardless of whether the download succeeded or failed. See also JavaScript Madness for more info.##Element size/position/scrolling and mouse position:
elm.style.pixelHeight/Widthin IE rather thanelm.offsetHeight/Width, but neither is reliable in IE, especially in quirks mode, and sometimes one gives a better result than the other.elm.offsetTopandelm.offsetLeftare often incorrectly reported, leading to finding positions of elements being incorrect, which is why popup elements etc are a few pixels off in a lot of cases.Also note that if an element (or a parent of the element) has a
displayofnonethen IE will raise an exception when accessing size/position attributes rather than returning0as Firefox does.Get the screen size (Getting the viewable area of the screen):
window.innerWidth/innerHeightdocument.documentElement.clientWidth/clientHeightdocument.body.clientWidth/clientHeightDocument scroll position/mouse position: This one is actually not defined by the w3c so is non-standard even in Firefox. To find the
scrollLeft/scrollTopof thedocument:Firefox and IE in quirks mode:
document.body.scrollLeft/scrollTopIE in standards mode:
document.documentElement.scrollLeft/scrollTopNOTE: Some other browsers use
pageXOffset/pageYOffsetas well.In order to get the position of the mouse cursor,
evt.clientXandevt.clientYinmousemoveevents will give the position relative to the document without adding the scroll position so the previous function will need to be incorporated:##Selections/ranges:
<textarea>and<input>selections:selectionStartandselectionEndare not implemented in IE, and there’s a proprietary "ranges" system in its place, see also How to get the caret column (not pixels) position in a textarea, in characters, from the start?.Getting the currently selected text in the document:
window.getSelection().toString()document.selection.createRange().text##Getting elements by ID:
document.getElementByIdcan also refer to thenameattribute in forms (depending which is defined first in the document) so it’s best not to have different elements which have the samenameandid. This dates back to the days whenidwasn’t a w3c standard.document.all(a proprietary IE-specific property) is significantly faster thandocument.getElementById, but it has other problems as it always prioritizesnamebeforeid. I personally use this code, falling back with additional checks just to be sure:##Problems with read only innerHTML:
IE does not support setting the innerHTML of
col,colGroup,frameSet,html,head,style,table,tBody,tFoot,tHead,title, andtrelements. Here’s a function which works around that for table-related elements:Also note that IE requires adding a
<tbody>to a<table>before appending<tr>s to that<tbody>element when creating usingdocument.createElement, for example:##Event differences:
Getting the
eventvariable: DOM events aren’t passed to functions in IE and are accessible aswindow.event. One common way of getting the event is to use e.g.elm.onmouseover = function(evt) {evt = evt||window.event}which defaults to
window.eventifevtis undefined.Key event code differences: Key event codes vary wildly, though if you look at Quirksmode or JavaScript Madness, it’s hardly specific to IE, Safari and Opera are different again.
Mouse event differences: the
buttonattribute in IE is a bit-flag which allows multiple mouse buttons at once:var isLeft = evt.button & 1)var isRight = evt.button & 2)var isCenter = evt.button & 4)The W3C model (supported by Firefox) is less flexible than the IE model is, with only a single button allowed at once with left as
0, right as2and center as1. Note that, as Peter-Paul Koch mentions, this is very counter-intuitive, as0usually means ‘no button’.offsetXandoffsetYare problematic and it’s probably best to avoid them in IE. A more reliable way to get theoffsetXandoffsetYin IE would be to get the position of the relatively positioned element and subtract it fromclientXandclientY.Also note that in IE to get a double click in a
clickevent you’d need to register both aclickanddblclickevent to a function. Firefox firesclickas well asdblclickwhen double clicking, so IE-specific detection is needed to have the same behaviour.Differences in the event handling model: Both the proprietary IE model and the Firefox model support handling of events from the bottom up, e.g. if there are events in both elements of
<div><span></span></div>then events will trigger in thespanthen thedivrather than the order which they’re bound if a traditional e.g.elm.onclick = function(evt) {}was used."Capture" events are generally only supported in Firefox etc, which will trigger the
divthen thespanevents in a top down order. IE haselm.setCapture()andelm.releaseCapture()for redirecting mouse events from the document to the element (elmin this case) before processing other events, but they have a number of performance and other issues so should probably be avoided.Firefox:
Attach:
elm.addEventListener(type, listener, useCapture [true/false])Detach:
elm.removeEventListener(type, listener, useCapture)(
typeis e.g.'mouseover'without theon)IE: Only a single event of a given type on an element can be added in IE – an exception is raised if more than one event of the same type is added. Also note that the
thisrefers towindowrather than the bound element in event functions (so is less useful):Attach:
elm.attachEvent(sEvent, fpNotify)Detach:
elm.detachEvent(sEvent, fpNotify)(
sEventis e.g.'onmouseover')Event attribute differences:
Stop events from being processed by any other listening functions:
Firefox:
evt.stopPropagation()IE:
evt.cancelBubble = trueStop e.g. key events from inserting characters or stopping checkboxes from getting checked:
Firefox:
evt.preventDefault()IE:
evt.returnValue = falseNote: Just returning
falseinkeydown,keypress,mousedown,mouseup,clickandresetwill also prevent default.Get the element which triggered the event:
Firefox:
evt.targetIE:
evt.srcElementGetting the element the mouse cursor moved away from:
evt.fromElementin IE isevt.targetin Firefox if in anonmouseoutevent, otherwiseevt.relatedTargetGetting the element the mouse cursor moved to:
evt.toElementin IE isevt.relatedTargetin Firefox if in anonmouseoutevent, otherwiseevt.targetNote:
evt.currentTarget(the element to which the event was bound) has no equivalent in IE.