w3c valid HTML 4.01 logo w3c valid CSS logo
Mouse Me!


Or Me!






Cross-Browser Mouse Event Handling
© 2009-10, Martin Rinehart (last update: 20100807)

Normally one would go to Peter-Paul Koch's book or his quirksmode.org site for cross browser JavaScript programming. Sadly, the mouse event handling information there is quite out of date. This is an update.

The Big Deals

Two simple steps will give you standards-based mouse-event JavaScript that works in most of the browsers in use today (mid 2010).
  1. Between <script> and </script> tags, or in a .js file, add this little function:
    
    function fixupMouse( event ) {
    
        event = event || window.event;
    
        var e = { event: event,
            target: event.target ? event.target : event.srcElement,
            which: event.which ? event.which :
                ( (event.button === 2) ? 3 : 1 ),
            x: event.x ? event.x : event.clientX,
            y: event.y ? event.y : event.clientY
        }
        return e;
    }
  2. In your event handler, call the fixupMouse() function:
     
    function myClickHandler( event ) {
        e = fixupMouse( event );
    
You now have, in "e", the following standards-based¹ properties: You also have e.event, the host object that you can use to access other event properties.

Test Your Browsers

There are two div objects (ids 'MouseMe' and 'OrMe') on the top-left corner of this page. They each report mouse events (down, up, over, out, move, click), stating the event type, the ID of the originater (e.target.id) and the value of e.which. Move events update the status bar, if there is one, with the latest location. Try them in any browsers you want to support. (Your author has tested MSIE 6, 7 and 8, recent Chrome, Firefox, Opera and Windows Safari, and, on Linux, Opera and Konqueror. Reports on others, especially telephones, are welcome—MartinRinehart at gmail dot com.)

Little Deals

If you attach your handler in the markup, be sure that you provide an argument named "event":
   <tag ... onmousedown='onMouseDown(event);'> 


No browser tested yet returns a middle button click and support for wheel spins is rare. For now, don't use the middle button. There are serious differences for the right button. Browsers display their context menus on a right click. Some also return a mouse event, and some don't. If you turn off the context menus your application can then use the right button, but your viewers may be disappointed if they lose those helpful menus.

Konqueror returns e.which === 65536 on the buttonless events (over, out, move). All the others report e.which === 1. Don't use e.which in a buttonless event handler.

The events returned if you mix mousedown/up with onclick and ondblclick are not standardized. Use either clicks or down/up events, but don't mix them.

If you only want working mouse events, you may stop right here. If you want to look under the hood, read on.

fixupMouse() Explained

function fixupMouse( event ) {

We'll create a handler with one parameter named "event".

event = event || window.event;

The browser should return the event as an argument to the handler function. MSIE does not. Instead, it creates window.event which we use here if event is undefined.

var e = {

We use JavaScript's very handy object notation to create our own object.

event: event,

The host object event has lots of information. Too much to copy so we'll just attach a reference to our little event.

target: event.target ? event.target : event.srcElement,

The standards-based browsers return event.target. MSIE returns event.srcElement, which this ternary picks if event.target doesn't exist.

which: event.which ? event.which :

The standards-based browsers provide event.which. 1 is the left button, 2 is the center button and 3 is the right button. Today's browsers do not support the center button so you really just have 1 and 3. And since the right button shows the browser's valuable context menu (some also return an event, but some don't) you should really handle just e.which === 1 .

( (event.button === 2) ? 3 : 1 ),

This is the MSIE part of the ternary started on the previous line. MSIE returns event.button with 1 for the left, 2 for the right and 4 for the center. That's arguably better as you could sum them for multiple buttons pressed at the same time. But it's unarguably non-standard. Here we return 3 for the right button.

x: event.x ? event.x : event.clientX,

All the tested browsers except MSIE and Firefox return the very handy event.x and event.y as the event's location relative to the top-left corner of the browser's client area. Firefox and MSIE return this in event.clientX and event.clientY.

y: event.y ? event.y : event.clientY

(See above.)

return e;

We have now brought our event up to a fully standards-compliant level ready to be used by your JavaScript as if all browsers followed the standards.

¹What is a standard? If W3C specifies it and all or most browsers support it you have a standard. If W3C specifies it and no browsers support it (middle mouse clicks, for example) you do not have a standard. If almost all browsers support one feature (event.x for example) it's semi-standard; W3C should add it.

# # #