DOM events
This is currently supported by Opera 7+, Mozilla/Firefox, Konqueror 3.0+, Safari/Chrome, Internet Explorer 9+ in standards mode and NetFront 3.3+. It is also partially supported by iCab 3, ICEBrowser 5+, and Tkhtml Hv3. Espial claim that Escape/Evo 5 supports this, but it does not support even the basics.
Note: Internet Explorer 8- on Windows does not comply with the standard here, so if you are testing, use a browser that supports the standard correctly, such as Opera. Internet Explorer 9+ drops support for the standard model in quirks mode and IE 7 compatibility mode, and will continue to need the Internet Explorer 8- workarounds. I will give details later on how to get support for Internet Explorer 8- on Windows as well. Internet Explorer on Mac does not support either the DOM or IE events models.
Problems with the traditional event models
Traditionally, browsers had a simple way to listen for events, and run scripts when that happened. The script could be held inside an appropriate event handler attribute, such as onclick="alert('here');"
. Internally, the browser would register this as an anonymous function, that a script could override:
referenceToElement.onclick = function () { alert('here'); };
Returning false from any event handler function would prevent the normal action from happening, such as preventing the browser following a link when it detected the click event.
In many basic applications, this was adequate. However, it has limits. If an event handler already exists, and you want to add functionality to it part way through your script, you would have to rewrite the function with both the new and old functionality. Then if you wanted to remove some functionality, you would have to rewrite it again. You might even have to write your own handler function management system, with one event handler that runs the appropriate functions in turn.
Another problem with the traditional model was that it never coped well with the possibility that two elements may detect the same event. Imagine that a link is inside a div, and both the link and the div are set up to detect the click event. When you click the link, should the link see the click? Or should the div see it? Or should both? If both should detect it, in what order should they see it; div first, or link first?
Initially, when Netscape introduced events, their answer was simple; the link should see it. Nothing more. Later, they allowed the div to see it as well, but only if you told it to capture the event. The div would then see the click, and after that, the link would see it (in Netscape's original implementation, the event would only be seen by the link if you explicitly told it to continue after the initial capture - this is not necessary in DOM 2 events). At the same time, Internet Explorer introduced an alternative version. By default, both the link and the div would see the click, and unlike in Netscape, the link would see it first. This was called bubbling.
Adding DOM event listeners
- ICEbrowser sometimes fails to detect the page's load event.
- ICEbrowser will forget to remove listeners if you reload, so the effect is cumulative.
- Tkhtml Hv3 versions before September 2007 fire events only in the bubbling order, but fire both the bubbling and capturing listeners (in that order).
The DOM 2 events module was designed to cope with all possibilities, so not only could you add multiple event handlers for a single event, but you could also say in what order elements should see the event. The DOM refers to these event handler functions as event listeners. The way to add an event listener is like this:
referenceToElement.addEventListener('nameOfEvent',referenceToFunction,phase)
You can add as many listeners for the same event on the same element as you want, but note that there is no way to guarantee in what order they will be run. (Trying to add the same event, function, and phase to the same element multiple times will result in it being added just once.) Note that, unlike with the traditional events models, it is not possible to obtain a reference to the event handler functions (this could previously done with referenceToElement.oneventname, but DOM 2 events does not provide any equivalent to list all the event handlers).
The name of the event is written like this: 'click', 'mouseover', or 'keyup'. The referenced function will be run in much the same way as with the traditional model. According to the spec, the 'referenceToFunction' parameter should actually be a reference to an object that has a method called 'handleEvent', and that method will be called instead. However, in practice, Opera 8+, Mozilla/Firefox, Konqueror 3.2+, Safari/Chrome, Internet Explorer 9+ and iCab implement this correctly, but the others do not. Aditionally, most authors are not even aware that this functionality exists. In most cases, it is easiest to just use a direct function reference.
The phase says in what order the event should be detected. False means the bubbling phase, and is usually the one you want to use. True means the capturing phase. Any event handlers added using the traditional techniques are treated as a bubbling event listener. The phase is actually very important to get right, since its behaviour is not straightforward. Capturing is special. According to the specification, if an element is set up to capture a click event (for example), and you click it, the event handler should not be run. It should only be run if you click on a child element inside the element. In other words, the capture phase is only used on ancestors of the target element.
In our earlier link and div example, assume that both elements are set up to detect the click event using both the capturing and bubbling phase. If you click the link, the specification says that the event listeners should be run in this order:
- Capture listeners for the div
- Bubbling listeners for the link
- Bubbling listeners for the div
This progression from listener to listener is known as propagation. You can check what stage the propagation is at by checking the eventObject.eventPhase property. It should be 1 during the capture phase, 2 during the bubble phase on the target element itself (in this case the link), and 3 during the bubbling phase on the target's ancestors. It can also be 0 if it is a manually created event object that has not yet been fired. See below for further details.
Note that some events (such as the load event) do not bubble up to ancestors, but they will still capture, so capture phase listeners will always see the events of their children (with load events detected in the capture phase on the document, this means they should see an event every time any image, plugin, or many other embedded file types load).
Also note that in the above example, only Opera 9.2-, Safari 1.1-, NetFront 3 and ICEBrowser follow the specification. Mozilla/Firefox, Opera 9.5+, Konqueror, Chrome/Safari 1.2+, Internet Explorer 9+, Netfront 4+ and iCab will fire the capture listeners on the link. Mozilla 1.7-/Firefox 1.0 will fire it before point 3. Opera 9.5+, Konqueror, Safari, iCab and Mozilla 1.8+/Firefox 1.5+ before point 2 giving this (commonly supported) event propagation:
- Capture listeners for the div
- Capture listeners for the link
- Bubbling listeners for the link
- Bubbling listeners for the div
That behaviour is wrong according to DOM 2 Events, but it is relied on by many Web pages, so it it unlikely that the browsers will follow the DOM 2 Events specification. It may be changed to be correct in DOM 3 (though it currently is not), in which case the other browsers can be expected to implement it that way as well. However, you should be aware that browsers may behave either way. Do not rely on the capturing phase firing on the target, since it is currently incompatible, and may well be changed at some point.
So now, to put this example into practice:
<div id="thediv"><a href="/" id="thelink">test</a></div>
...
var oDiv = document.getElementById('thediv');
var oLink = document.getElementById('thelink');
oDiv.addEventListener('click',function (e) {
alert('1. Div capture ran');
},true);
oDiv.addEventListener('click',function (e) {
alert('3. Div bubble ran');
},false);
oLink.addEventListener('click',function (e) {
alert('Link capture ran - browser does not follow the specification');
},true);
oLink.addEventListener('click',function (e) {
alert('2. Link bubble ran (first listener)');
},false);
oLink.addEventListener('click',function (e) {
alert('2. Link bubble ran (second listener)');
},false);
Test it here: click this link to activate the event listeners.
Note that some browsers will run the first link bubble listener before the second, and some will run the second before the first - the standard does not say in which order they should be run, and it even allows them to be run at the same time - you should not rely on any specific behaviour here).
Removing event listeners
Removing event listeners is as easy as adding them:
referenceToElement.removeEventListener('nameOfEvent',referenceToFunction,phase)
Note that you can remove event listeners at any time, and you must remove them using the exact same parameters as you added them with. This can be difficult if you used anonymous functions as I did in the example above. If you use anonymous functions, you can use the arguments.callee property provided by JavaScript to reference the function and remove the listener. This reference can only be done from inside the listener itself. So for example, to add an event listener that removes itself after it has fired once, you can use:
oLink.addEventListener('click',function (e) {
alert('Link bubble fired');
this.removeEventListener('click',arguments.callee,false);
},false);
Test it here: fire the event listener and see if it can remove itself (you should get an alert the first time you click the link).
Referencing the elements that detect the event
You may notice that I use the 'this' keyword in the last example. Inside an event listener function, the 'this' keyword is a reference to the element that is currently detecting the event. In the first example, that could be the div, or the link, depending on which one the event listener is attached to. You may also notice that the functions accept a parameter (I called it 'e', but you could call it whatever you want). That parameter, as with the original Netscape event model, is the event object, and contains a lot of information about the event. For now, I will stick with the basics.
eventObject.currentTarget is the same as 'this' - it refers to the element that the listener function is attached to (if the same function is attached as a listener to several elements, it will be a reference to the listener that is currently being run).
eventObject.target is the element that the event actually happened to. In the case of the earlier example, this would be the link. If there was a span inside the link, and you clicked that, then eventObject.target would be a reference to the span, even if the span itself did not have any listeners attached directly to it. Note that older Safari and Konqueror sometimes make the target point to the textNode inside the element. That is incorrect behaviour, and is fixed in current versions. If this is likely to cause problems, check the nodeType of the target. If it is a text or CDATA node, then you will need to use its parent node instead.
var theTarget = e.target;
if( theTarget && ( e.target.nodeType == 3 || e.target.nodeType == 4 ) ) {
theTarget = theTarget.parentNode;
}
Test it here: click anywhere within this sentence to see what element you clicked.
Some events (such as mouseover) will also provide eventObject.relatedTarget. This will be a reference to the element the mouse was over before it was moved over the current element. With mutation events, it is typically (but not always) the parent node of the node being manipulated.
Obtaining other information from the event
Information such as mouse button and position, keyCode, ctrlKey, altKey, shiftKey, and detail (such as click count) are available in the same way as with the older model (see the HTML events section of this tutorial for more details). They are available as properties of the event object. Mutation events can also provide prevValue, newValue, attrName and attrChange values (see the DOM 2 events specification for more details).
Preventing the default action
In the example above, clicking the links will activate the listeners, but the link will be followed anyway. Returning false from a listener function does not work like it used to in the traditional models. Instead, you must use eventObject.preventDefault()
- only one event listener needs to run this method for the default action to be prevented.
Not all event types can be cancelled (the load event, for example, has no default action, and cannot be cancelled). If an event is of a type that can be cancelled, the eventObject.cancelable property will be true.
oLink.addEventListener('click',function (e) {
alert('Link detected a click. Cancellable: '+e.cancellable);
e.preventDefault();
},false);
Test it here: if you click this link, you should remain on this page.
Preventing other listeners from seeing the event
- Tkhtml Hv3 does this correctly, but because versions before September 2007 activate the listeners in the wrong order, they appear to fail here.
When an event is being processed by the event listeners, it is possible for any event listener to prevent any more event listeners in the propagation chain from seeing the event. In the example above, the div's capture phase click event listener could prevent the other event listeners from seeing the click event, by using the eventObject.stopPropagation()
method. Note that you can check if the event is a type that can bubble by checking the eventObject.bubbles property.
The stopPropagation method only prevents listeners further along the propagation chain from seeing the event. For example, I added two event listeners to the link in the bubble phase. If one of these uses the stopPropagation method, the other one will always run, no matter in what order the browser ran them. The method would only stop the event listener that was added to the div in the bubble phase.
<div id="thediv"><a href="/" id="thelink">test</a></div>
...
var oDiv = document.getElementById('thediv');
var oLink = document.getElementById('thelink');
oDiv.addEventListener('click',function (e) {
alert('Div capture ran. Now stopping propagation.');
e.stopPropagation();
},true);
oLink.addEventListener('click',function (e) {
alert('This alert should never appear');
},false);
Test it here: click this link to activate the event listeners.
More than basic events
As well as the basic events defined in HTML, DOM 2 provides aditional event types that can be detected. A useful example of these are the mutation events. These fire when elements or descendant nodes are added, modified, or removed by a script (I will not go into more detail here, see the DOM 2 events specification for more details). They are partially supported by Opera, Mozilla/Firefox, Konqueror, Safari/Chrome and Internet Explorer 9+. Note that browser support for 'DOMNodeInsertedIntoDocument', 'DOMNodeRemovedFromDocument', and 'DOMSubtreeModified' events is currently very poor, so these events should not be used. Safari 4- also does not work with the 'DOMAttrModified' event. Note that Opera 7.1, Safari 1.2, and Konqueror 3.2-3.3 will crash if you attempt to use any mutation events. Opera 7.2+, Safari 1.3+, and Konqueror 3.4+ will work correctly. Konqueror 4.2.2 seems to have lost all support for all mutation events.
The DOM does not provide any way to work out if the event will fire or not. If a browser does not support an event, it will still allow you to add the event listener, but it will not fire the event. It is possible to check if a browser supports the required events model using hasFeature, but this is not a perfect indication, since a browser will only claim to support the feature if its support is relatively complete. Browsers may support a large amount of the feature (enough for what you need) but still not claim to support it. Assuming you want a relatively complete implementation, instead of support for just one or two event types, checking for mutation events is as simple as this:
if( document.implementation.hasFeature('MutationEvents','2.0') )
Note that this will exclude Mozilla/Firefox, even though it does support many of the common mutation events. You could alternatively check for the interface as well, since Mozilla/Firefox (Opera, newer Safari/Chrome and Internet Explorer 9+ provide it too, but not Konqueror or older Safari) should provide this:
if( document.implementation.hasFeature('MutationEvents','2.0') || window.MutationEvent )
Some other types of event may also cause problems, not because the browsers do not support them, but because the browsers support them only on the wrong object. The load event is the worst behaved in this respect. According to the original DOM 2 events specification, the load event should be detected on the document object. Unfortunately, the traditional models used the body tag, and mapped it to the window object. As a result, when browsers added support for it via DOM, most of them initially chose to detect it only on the window object. Future specifications will make it more clear that it should only work with the window object.
Opera 10.1-, and similarly aged versions of Konqueror, Safari/Chrome and NetFront correctly detected it on the document object (as well as on the window object, for compatibility reasons). This was changed in Opera 10.5+, and similarly aged versions of the other browsers, to follow the Mozilla behaviour. Internet Explorer 9+ also follows the Mozilla behaviour. New implementations may theoretically follow the DOM specification, and only detect it on the document object. For this reason, you should check if the window and document objects can detect events before adding listeners to them. If the browser allows you to attach event listeners to the window, you can assume that it can detect the load event there. This is true for all current implementations.
Note also that as described above, you should always use the bubble phase when detecting load events, or they will repeatedly fire when other embedded content loads. However, note that Mozilla/Firefox and iCab 3 cannot capture load events, Opera 9.5+, Safari/Chrome, Internet Explorer 9+ and Konqueror only capture load events when the listener is attached to the document (not the window), and only Opera 9.2- and ICEBrowser correctly always capture load events. Unless you really know what you are doing, and you have worked around all the incompatibilities, you should only ever detect load events in the bubbling phase. Most importantly, do not rely on the implementations of browsers that do not capture load events; they are wrong, and the same code will not work the same way in other browsers.
if( window.addEventListener ) {
window.addEventListener('load',handlerFunction,false);
} else if( document.addEventListener ) {
document.addEventListener('load',handlerFunction,false);
}
Bad news; your browser did not detect the load event using this script.
The situation is similar for several other events, such as scroll and resize. They will also require you to use the window and document branches.
Manually firing events
- Safari/Chrome makes the keyCode and charCode properties read-only, so it is not possible to simulate specific keys when manually firing events.
- Mozilla/Firefox incorrectly generates the default action for mouse and printable character keyboard events, when they are dispatched on form elements.
- iCab 3, ICEbrowser, NetFront 3.3- and Tkhtml Hv3 cannot manually fire events (ICEbrowser, NetFront 3.3- and Tkhtml Hv3 provide the methods, but they do not work correctly).
With the old events model, it was easy to fire event handlers manually, using referenceToElement.oneventname()
- since there was only one possible handler, and it was treated as a method, it could be run as easily as any other method. With the DOM 2 events model, this is not possible, since there may be multiple handlers for the same event. The DOM provides a few methods that can be used to create and prepare a fake event object, then use it to fire the event on any target.
The element you fire an event on does not have to be listening for that event, since potentially, the parent element may also be listening for that event.
Note that manually firing an event does not generate the default action associated with that event. For example, manually firing a focus event does not cause the element to receive focus (you must use its focus method for that), manually firing a submit event does not submit a form (use the submit method), manually firing a key event does not cause that letter to appear in a focused text input, and manually firing a click event on a link does not cause the link to be activated, etc. In the case of UI events, this is important for security reasons, as it prevents scripts from simulating user actions that interact with the browser itself.
There are five DOM 2 event modules, and they map directly to the names of the DOM features;
- Events
- Covers all event types.
- HTMLEvents
- Covers 'abort', 'blur', 'change', 'error', 'focus', 'load', 'reset', 'resize', 'scroll', 'select', 'submit', and 'unload'.
- UIEvents
- Covers 'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', and (since they do not have their own key events module in DOM 2) it also covers 'keydown', 'keypress', and 'keyup'. Also indirectly covers MouseEvents.
- MouseEvents
- Covers 'click', 'mousedown', 'mousemove', 'mouseout', 'mouseover', and 'mouseup'.
- MutationEvents
- Covers 'DOMAttrModified', 'DOMNodeInserted', 'DOMNodeRemoved', 'DOMCharacterDataModified', 'DOMNodeInsertedIntoDocument', 'DOMNodeRemovedFromDocument', and 'DOMSubtreeModified'.
Other events (such as 'dblclick') are not part of the specification, and browsers are not required to support them. Browsers that do support them will either choose an appropriate event module to class them as - dblclick would fit very well into MouseEvents - or they will create a new module. You will need to know what module the browser has put the events into when you create these events.
Fake event objects are created using the document.createEvent method, and the appropriate event module should be specified when creating it. They are then prepared using the appropriate method, and finally they are then fired on the desired target element using the element.dispatchEvent method. If you use the more specific event type instead of the generic event type, you can provide more information when preparing it. dispatchEvent will return false if the detault action was prevented.
The event object methods for preparing the event object properties for the various event modules are:
- HTMLEvents and generic Events
initEvent( 'type', bubbles, cancelable )
- UIEvents
initUIEvent( 'type', bubbles, cancelable, windowObject, detail )
- MouseEvents
initMouseEvent( 'type', bubbles, cancelable, windowObject, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget )
- MutationEvents
Note, although prevValue, newValue, and attrName can all be null, attrChange must always be provided, even if the event is not a DOMAttrModified event (set it to 1, 2, or 3)initMutationEvent( 'type', bubbles, cancelable, relatedNode, prevValue, newValue, attrName, attrChange )
MouseEvents are a subclass of UIEvents, and all event modules are a subclass of Events, so if you create a mouse event object, it will also inherit the initUIEvent and initEvent methods from the more generic UIEvents and Events interfaces. You can choose which init*Event method you want to use when preparing the event.
The following is an example of firing a click event:
var fireOnThis = document.getElementById('someID');
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent( 'click', true, true, window, 1, 12, 345, 7, 220, false, false, true, false, 0, null );
fireOnThis.dispatchEvent(evObj);
Test it here: move your mouse over here and I will manually fire a mouseup event instead.
The following is another example of firing a click event, this time using the generic initEvent method, and leaving undefined properties at their default values (even when using the generic initEvent or initUIEvent, you should still use the exact module name, and not a generic module, or it will not work in Mozilla/Firefox, Konqueror, or Safari/Chrome):
var fireOnThis = document.getElementById('someID');
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( 'click', true, true );
fireOnThis.dispatchEvent(evObj);
Key events are a little harder, because Mozilla/Firefox does not implement the standard correctly, and does not allow you to create key events using generic UIEvents (it may just crash). Instead, it provides a proprietary module 'KeyEvents', and initialisation method 'initKeyEvent'. The proprietary initKeyEvent method expects the following parameters: 'type', bubbles, cancelable, windowObject, ctrlKey, altKey, shiftKey, metaKey, keyCode, charCode. You can use if(window.KeyEvent)
to detect support for the KeyEvents module. Browsers that expect you to use UIEvents do not have a specific initialisation function for key events, so some properties must be added manually:
var fireOnThis = document.getElementById('someID');
if( window.KeyEvent ) {
var evObj = document.createEvent('KeyEvents');
evObj.initKeyEvent( 'keyup', true, true, window, false, false, false, false, 13, 0 );
} else {
var evObj = document.createEvent('UIEvents');
evObj.initUIEvent( 'keyup', true, true, window, 1 );
evObj.keyCode = 13;
}
fireOnThis.dispatchEvent(evObj);
Getting support for legacy Internet Explorer on Windows
Internet Explorer 8- on Windows does not provide any of the DOM 2 Events methods, and provides very few of the properties of the event object. Internet Explorer 9+ also does not support the DOM 2 Events methods on pages that trigger quirks mode. Pages rendered in IE9+'s IE 7 compatibility mode (enabled automatically or by the user on some pages, or by default for intranet sites) will also not be able to use the standard model. Version 5.0+ (including IE9+ in quirks or standards mode) does provide a similar system that is much more limited in its capabilities, but if you need legacy Internet Explorer support, you will have to accept the differences and limitations, make sure your code does not rely on the parts that Internet Explorer is missing, and implement the branching code I will show you here.
Adding and removing listeners
Adding and removing event listeners is done using these methods:
referenceToElement.attachEvent('onNameOfEvent',referenceToFunction);
referenceToElement.detachEvent('onNameOfEvent',referenceToFunction);
These are almost synonymous with the addEventListener and removeEventListener methods, but they are unable to specify a phase. The Internet Explorer model only detects events in the bubbling phase, not capture. It also requires 'on' to be included at the start of the eventname, so for the click event, you should use 'onclick' in IE, and not 'click'. (Note also that IE 8- only supports the basic event types - it does not support any of the advanced types, such as mutation events.) If you need legacy Internet Explorer support as well, you should use this code:
function eventHandler(e) {
alert('Div bubble ran');
}
var oDiv = document.getElementById('thediv');
if( oDiv.addEventListener ) {
oDiv.addEventListener('click',eventHandler,false);
} else if( oDiv.attachEvent ) {
oDiv.attachEvent('onclick',eventHandler);
}
Test it here: this text has been set up to detect click events, and should alert a message when clicked.
Referencing the elements that detect the event
Internet Explorer's model is more annoying here. The 'this' keyword is a reference to the window object. There is no equivalent to the eventObject.currentTarget property. Internet Explorer's model makes it impossible to see what element is currently processing the event.
It is possible to reference the actual target of the event, using the eventObject.srcElement property, which is equivalent to the eventObject.target property provided by DOM 2 Events. Unlike the way it works with traditional event models, IE does correctly provide the event object as an argument to the handler function when you use attachEvent. There is no need to check if window.event is needed instead, because it is not needed. However, it is important to note that in IE, the event object only exists for as long as the initial event propagation thread. It cannot be stored and reference later, or used in timeout threads. To use srcElement, simply detect what you need (make sure the standards compliant check is made first):
var theTarget = e.target ? e.target : e.srcElement;
if( theTarget && ( theTarget.nodeType == 3 || theTarget.nodeType == 4 ) ) {
theTarget = theTarget.parentNode;
}
Test it here: click anywhere within this sentence to see what element you clicked.
You can also do the same to get the equivalent to eventObject.relatedTarget - which is known as eventObject.fromElement in IE. It is available for mouseover and mouseout events.
var relTarget = e.relatedTarget ? e.relatedTarget : e.fromElement;
Preventing the default action
The IE model does not provide eventObject.preventDefault() but provides an alternative. The event object has a property called 'returnValue' that will perform the equivalent functionality if it is set to false. Setting this value in other browsers will not cause any problems, so the easiest way to support IE as well is like this:
if( e.preventDefault ) { e.preventDefault(); }
e.returnValue = false;
Test it here: if you click this link, you should remain on this page.
It is not possible to check if the event is a type that can be cancelled in IE.
Preventing other listeners from seeing the event
The IE model does not provide the stopPropagation method (probably because it only supports bubbling). Instead, it uses a property called 'cancelBubble', which must be set to true to prevent propagation. It is not possible to check if the event is a type that can bubble in the IE model.
if( e.stopPropagation ) { e.stopPropagation(); }
e.cancelBubble = true;
Test it here: click this link to activate the event listeners.
Detecting the load event
Legacy Internet Explorer detects the load event on the window object, using the usual attachEvent method. This makes the load event listener (shown above) require one more branch:
if( window.addEventListener ) {
window.addEventListener('load',handlerFunction,false);
} else if( document.addEventListener ) {
document.addEventListener('load',handlerFunction,false);
} else if( window.attachEvent ) {
window.attachEvent('onload',handlerFunction);
}
Bad news; your browser did not detect the load event using this script.
Manually firing events
This is a little more messy than the other event handling, since the initialisation is considerably different. The Internet Explorer model has a method for manually firing events, called fireEvent, and it is available in IE 5.5+ (there is no equivalent in IE 5.0). In its simplest form, this is similar to the DOM version, but the bubbles and cancelable properties are not available. The fireEvent method expects to be passed either one or two parameters. The first should be the name of the event (for example; 'onchange'), and the optional second parameter should be an event object to be passed to the handler.
Note that even though the window object can detect several events in IE (such as load, unload, scroll, and resize - all of which should, according to the spec, be detected by the document object, not window), it is not possible to use fireEvent on the window object.
var fireOnThis = document.getElementById('someID');
if( document.createEvent ) {
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( 'mousemove', true, false );
fireOnThis.dispatchEvent(evObj);
} else if( document.createEventObject ) {
fireOnThis.fireEvent('onmousemove');
}
If you want to specify more details, you will need to use the createEventObject method in IE to replicate the createEvent and init*Event methods of the DOM. The createEventObject method normally returns a blank event object, and you will need to define parameters yourself. You can optionally pass an existing event object to createEventObject, and it will use that as a template when preparing the new event object. Usually, you will not need to pass it any arguments.
var fireOnThis = document.getElementById('someID');
if( document.createEvent ) {
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent( 'mousemove', true, false, window, 0, 12, 345, 7, 220, false, false, true, false, 0, null );
fireOnThis.dispatchEvent(evObj);
} else if( document.createEventObject ) {
var evObj = document.createEventObject();
evObj.detail = 0;
evObj.screenX = 12;
evObj.screenY = 345;
evObj.clientX = 7;
evObj.clientY = 220;
evObj.ctrlKey = false;
evObj.altKey = false;
evObj.shiftKey = true;
evObj.metaKey = false;
evObj.button = 0;
evObj.relatedTarget = null;
fireOnThis.fireEvent('onmousemove',evObj);
}
Test it here: move your mouse over here and I will manually fire a mouseup event instead.
Last modified: 4 April 2011