For those of you who are too lazy to keep up with the standards of the current JavaScript versions, this will suffice:
Expand|Select|Wrap|Line Numbers
- elem.onmouseup = SomeFunction;
- Only one function per event trigger
- No control over bubbling/capturing
- Dynamic addition and removal of events requires creation and deletion of objects
- It's old
The correct, modern way of handling event triggers are these methods:
- addEventListener, removeEventListener
- attachEvent, detachEvent
You see that there are two different ways, right? That's because, yet again, Microsoft decided to impose their own methods on us. In concept, these pairs of functions do the exact same thing, but in reality they don't. Microsoft's way (attachEvent/detachEvent) does not allow you to control whether or not you want to capture events.
The fact that there are two different sets of methods for doing this means that we need to know which ones the browser supports in order to know which ones to use. You could do so with if statements checking whether the browser supports addEventListener or attachEvent, but you'll likely have so many event triggers that it won't be practical. So, I've written two functions do it for you:
Expand|Select|Wrap|Line Numbers
- /**
- * Add an event listener to an object
- * @param object
- * @param evt event
- * @param func function
- * @param capture
- * @return boolean
- */
- function AddEvent(object, evt, func, capture)
- {
- if(typeof func != 'function')
- {
- return false;
- }
- if(object.addEventListener)
- {
- object.addEventListener(evt, func, capture);
- return true;
- }
- else if(object.attachEvent)
- {
- object.attachEvent('on' + evt, func);
- return true;
- }
- return false;
- }
- /**
- * Removes an event listener
- * @param object
- * @param evt event
- * @param func function
- * @param capture
- * @return boolean
- */
- function RemoveEvent(object, evt, func, capture)
- {
- if(typeof func != 'function')
- {
- return false;
- }
- if(object.removeEventListener)
- {
- object.removeEventListener(evt, func, capture);
- return true;
- }
- else if(object.detachEvent)
- {
- object.detachEvent('on' + evt, func);
- return true;
- }
- return false;
- }
Here's how to use them:
Expand|Select|Wrap|Line Numbers
- AddEvent(elem, 'mouseup', SomeFunction, false);
- RemoveEvent(elem, 'mouseup', SomeFunction, false);
- The first parameter is an element to add the event listener to
- The second parameter is the name of the event (without "on")
- The third parameter is the function (the actual function object with the parentheses)
- The last parameter is a boolean asking determining whether or not to capture the event
This will simplify your code. The only thing that you have to look out for is that even if you set the last parameter to true, it will still bubble in Internet Explorer instead of capture, so you still have to code for bubbling. Those are the breaks.
These functions will return false if neither of these methods are available, but all modern browsers support at least one of these methods, so it's safe to ignore it.
You should keep both of these events in a global JavaScript file that you use in all of your scripts to simplify event handling.
Original Source: Normalizing Event Triggers in JavaScript
Normalizing Event Objects in JavaScript
Just like almost everything worth using in JavaScript, Microsoft's Event object and the standard Event object are not the same. Because of this, we'll need to normalize the Event object in order to use it.
For those of you who are unfamiliar with JavaScript's Event objects, they are automatically sent to Function objects that are attached to an event trigger as the first parameter, no matter what you do.
The Event object has a lot of different properties, a lot of which are not cross-browser compatible. Differences consist of:
- layerX/layerY and offsetX/offsetY
- relatedTarget and fromElement/toElement
- target and srcElement
- keyCode and charCode
So, I wrote a function to normalize all of these into this variables (respectively):
- offsetX/offsetY
- relatedTarget
- src
- key
You can, of course, change the names of the variables in the follow function if you'd like to. This will make it so that you can use event objects without worrying about cross-browser issues.
Expand|Select|Wrap|Line Numbers
- /**
- * Gets an event with all needed properties
- * @param e event
- * @return event object
- */
- function GetEvent(e)
- {
- if(!e)
- {
- e = window.event;
- }
- if(e.layerX)
- {
- e.offsetX = e.layerX;
- e.offsetY = e.layerY;
- }
- if(e.type == 'mouseover' && !e.relatedTarget)
- {
- e.relatedTarget = e.fromElement;
- }
- else if(e.type == 'mouseout' && !e.relatedTarget)
- {
- e.relatedTarget = e.toElement;
- }
- e.src = e.srcElement || e.target;
- e.key = e.keyCode || e.charCode;
- return e;
- }
Here's how you use it:
Expand|Select|Wrap|Line Numbers
- function HandleEvent(e)
- {
- // Normalize the event
- e = GetEvent(e);
- // Do stuff with the event object
- }
Original Source: Normalizing Event Objects in JavaScript