I like to remove all the javascript from the page and place it in external files. This cleans up your XHTML code, lightens your page and makes maintenance easier, besides being W3C compliant. All javascript including onload, onmousedown, onkeypress etc. events should be removed. There should be no Javascript blocks in the HEAD or BODY of the page.
With a W3C compliant browser it should be possible to use the following to add an event to any element of the DOM.
[object].addEventListener( Event , Listener , useCapture );
useCapture can be set true or false. If set true then all events of the type specified in Event will be sent to the Listener before going elsewhere.
Internet Explorer, of course, has it's own proprietary method:
[object].addEvent( Event , Listener );
One big difference between the W3C compliant and more err... proprietary browsers is the syntax of the Event. Luckily it is a simple difference. IE uses events as they would appear within inline javascript - onload, onmousedown, onkeypress etc. W3C compliant browsers drop the 'on'. Easy to code around.
These functions will then work for Gecko based browsers ( Firefox, Mozilla, Opera, Netscape 6+, Safari, Konqueror etc..) and Internet Explorer.
Grand so, we're sorted.
Not quite.
Apparently neither of these functions works in IE5 for the Mac. There is hope. Simon Willison came up with a solution for stuffing the window.onload handler. I have extended it so that it will stuff any given handler on any given element:
eval( "var onTarget = Target.on" + theEvent + ";" );if ( onTarget ) {onTarget = function piggyback() {onTarget();Handler();};}
As you can clearly see :) this basically does a concatenation of the functions, stacking them together and pushing them back into the specified event handler on the element.
Note: this code is totally theoretical, although valid (I think). It is meant to account for misbehaviour in IE 5 on the Mac. I would be grateful if someone could test the complete function below on a Mac and let me know the results
Update (17th October 2004): The theoretcial portion of the code does not work and actually stops the script working on a Mac. I will be doing some testing soon with a real live mac and I should have the kinks ironed out before too long. Meanwhile you willhave to use window.load, which you can only invoke once per page so make sure the initiation function it calls covers everything you need.
We want to make this code as reusable and flexible as possible so we create a function that will take all the arguments we may have to pass and returns the result of attempting to add the handler.
The parameters that are passed to the function are:
function addHandler( Target , theEvent , Handler, useCapture ) {// (c) Mark Lennox of http://www.webpusher.ie 2004eval( "var onTarget = Target.on" + theEvent + ";" );if ( Target.addEventListener ) {Target.addEventListener( theEvent , Handler , useCapture );} else if ( Target.attachEvent ) {Target.attachEvent( "on" + theEvent , Handler );} else if ( onTarget ) { // theory startonTarget = function piggyback() {onTarget();Handler();};} else { onTarget = Handler(); } // theory endreturn true; // for Netscape 6}
The structure of this function is similar to the addEvent function developed by Scott Andrew and the 'event stuffer' portion was inspired by Scott Willison.
So to use this to add an onLoad event to your webpage you would include the javascript function above in an external file, then write another external Javascript file that would call that function like so:
addHandler( window, 'load', initPage , false );initPage = function() {:::}
And you are done. This works with Netscape 4.7+, IE 4+, Mozilla, Firefox and Opera on windows. It also works fine on Firefox and Mozilla on Linux, but not Konqueror (yet). Things are a little worrying on the Mac where the script in its current incarnation does not work in any flavour of IE.
The function can be used to add events to anything, but you must remember that page elements don't exist until the page is loaded so:
addHandler( window, 'load' , initPage , false );initPage = function() {addHandler( document.image["Coalminer"] , 'click' , showLargeImage , false );}
Go crazy! Take it. Use it. But if you do, I would appreciate a link back to this site.
Thanks.