IE does not support setting the innerHTML of col
, colGroup
, frameSet
, html
, head
, style
, table
, tBody
, tFoot
, tHead
, title
, and tr
elements. Here's a function which works around that for table-related elements:
function setHTML(elm, html) {
// Try innerHTML first
try {
elm.innerHTML = html;
} catch (exc) {
function getElm(html) {
// Create a new element and return the first child
var e = document.createElement('div');
e.innerHTML = html;
return e.firstChild;
};
function replace(elms) {
// Remove the old elements from 'elm'
while (elm.children.length) {
elm.removeChild(elm.firstChild);
}
// Add the new elements from 'elms' to 'elm'
for (var x=0; x' + html + ''));
} else if (['tbody', 'tfoot', 'thead'].indexOf(tn) != -1) {
replace(getElm('').firstChild);
} else if (tn === 'tr') {
replace(getElm('').firstChild.firstChild);
} else {
throw exc;
};
};
};
Also note that IE requires adding a to a before appending s to that element when creating using document.createElement
, for example:
var table = document.createElement('table');
var tbody = document.createElement('tbody');
var tr = document.createElement('tr');
var td = document.createElement('td');
table.appendChild(tbody);
tbody.appendChild(tr);
tr.appendChild(td);
// and so on
Event differences:
Getting the event
variable: DOM events aren't passed to functions in IE and are accessible as window.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.event
if evt
is 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 button
attribute in IE is a bit-flag which allows multiple mouse buttons at once:
- Left: 1 (
var isLeft = evt.button & 1
)
- Right: 2 (
var isRight = evt.button & 2
)
Center: 4 (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 as 2
and center as 1
. Note that, as Peter-Paul Koch mentions, this is very counter-intuitive, as 0
usually means 'no button'.
offsetX
and offsetY
are problematic and it's probably best to avoid them in IE. A more reliable way to get the offsetX
and offsetY
in IE would be to get the position of the relatively positioned element and subtract it from clientX
and clientY
.
Also note that in IE to get a double click in a click
event you'd need to register both a click
and dblclick
event to a function. Firefox fires click
as well as dblclick
when 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
then events will trigger in the span
then the div
rather 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 div
then the span
events in a top down order. IE has elm.setCapture()
and elm.releaseCapture()
for redirecting mouse events from the document to the element (elm
in 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)
(type
is e.g. 'mouseover'
without the on
)
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 this
refers to window
rather than the bound element in event functions (so is less useful):
Attach: elm.attachEvent(sEvent, fpNotify)
Detach: elm.detachEvent(sEvent, fpNotify)
(sEvent
is e.g. 'onmouseover'
)
Event attribute differences:
Stop events from being processed by any other listening functions:
Firefox: evt.stopPropagation()
IE: evt.cancelBubble = true
Stop e.g. key events from inserting characters or stopping checkboxes from getting checked:
Firefox: evt.preventDefault()
IE: evt.returnValue = false
Note: Just returning false
in keydown
, keypress
, mousedown
, mouseup
, click
and reset
will also prevent default.
Get the element which triggered the event:
Firefox: evt.target
IE: evt.srcElement
Getting the element the mouse cursor moved away from: evt.fromElement
in IE is evt.target
in Firefox if in an onmouseout
event, otherwise evt.relatedTarget
Getting the element the mouse cursor moved to: evt.toElement
in IE is evt.relatedTarget
in Firefox if in an onmouseout
event, otherwise evt.target
Note: evt.currentTarget
(the element to which the event was bound) has no equivalent in IE.