If you wish to capture object events using Javascript, the challenge is to support the event data on different browsers. This demo shows one method of correctly identifying the object which triggered the event. Some of the methods used in this demo to attach event handlers to objects only work on browsers which support the DOM getElementById() and getElementsByTagName() methods (IE5 and up, Mozilla, Netscape 6 and up, Safari, Opera, etc.)
When you click on one of the radio buttons, text appears in the input box which shows the value of the clicked radio button.
The Javascript used for this function is:
function eventTrigger (e) { if (! e) e = event; return e.target || e.srcElement; } function radioClick (e) { var obj = eventTrigger (e); var notify = document.getElementById && document.getElementById ('notify'); if (notify) notify.value = 'You clicked on ' + obj.value; return true; }
For each of the buttons, the onclick event is used to see that the click has happened and to update the text box. Each of the radio buttons has the event assigned in a different way to demonstrate different possibilities. Normally one would use one of these methods for all of the buttons in the group.
The first radio button object in the sample form has its onclick handler set to the radioClick() method:
<input type="radio" name="radios" value="First" onclick="return radioClick (event)"/>
The eventTrigger() method returns the triggering object for all of our targeted browsers (Internet Explorer, Mozilla, Safari, Opera):
Since we explicitly define the onclick handler on the first radio button to pass the global object event to radioClick(), our method always has a reference to the triggering event. However, the second and third radio buttons do not have the handler set in the HTML, but using DHTML.
Safari treats events on links a bit differently than other browsers. We take this HTML:
<a href="#" onclick="return linkClick (event)">Link event test</a>
and this Javascript:
function linkClick (e) { var obj = eventTrigger (e); var str = obj.innerHTML + "\n"; if (obj.tagName != 'A') obj = obj.parentNode; str += obj.innerHTML; alert (str); return false; }
we end up with a link we can test:
Clicking on the link in Safari, we see the alert box on the right, but other browsers show the same object twice. Safari is returning the text within the link as the object which triggered the event, rather than the actual link object itself. Because of this, you need to test the trigger object returned from eventTrigger() in cases such as this.
You need to be careful that you only apply this technique to events generated by links. Another method is to test if the object returned by eventTrigger() has an onclick attribute, but you would then need to take care to only use this with onclick events.
The second button's onclick handler is not set in the HTML, but we do uniquely identify the object:
<input id="second" type="radio" name="radios" value="Second"/> Second
and the event is set with this function which is called when the page has loaded:
function load2 () { var btn = document.getElementById ('second'); if (btn) btn.onclick = radioClick; }
This function tests that the button is indeed found before setting the onclick event, in case the id attribute gets cleared from the button.
When we set the onload function this way, we are not guaranteed that our event handler will get the triggering event as its first parameter. In fact, Internet Explorer does not do so, which is why our eventTrigger() method checks the argument to see if it has a value, and uses the global event variable if not. We can't use the global event variable all the time since it is not available in our function to Mozilla-based browsers. This is why our eventTrigger() function checks if the parameter is valid and uses the global event variable if not.
The HTML for the third radio button contains neither an onclick attribute nor an identifier:
<input type="radio" name="radios" value="Third"/> Third
Its onload handler is set by a function which sets the handler for all of our radio buttons in the radios group which doesn't already have an onclick handler set:
function loadrest () { var list = document.getElementsByTagName ('input'); if (! list) return; for (var i = 0; i < list.length; ++i) if (list[i].name == 'radios' && ! list[i].onclick) list[i].onclick = radioClick; }
This function goes through all <input/> objects in the document, finding those which have a name of radios. For each of those objects, it tests whether onclick was already set, and assigns radioClick() if not. As with the second button's script, loadrest() tries to be careful in case the HTML contains no <input/> objects.
The functions used to define the onclick event for the second and third buttons require that Javascript be used to set the event. This page uses the window's onload event to call the functions:
function doload () { if (document.getElementsByTagName && document.getElementsByTagName ('body')) { load2 (); loadrest (); } } window.onload = doload;
The load function is careful to only call the functions which set the onclick event handlers only if DOM functions are available and working. There are some browsers which will return true if you test for the existence of document.getElementById but don't actually implement the function, which is why this function not only tests for a function but tests the result of calling it.
If you are only using the method demonstrated for the third button to set the onclick event for all the buttons, you can set the onload event directly to loadrest, being careful to test for any DOM functions you may use.
There are other methods which can be used to call these functions: