Prev: Ping
Next: onmouseleave Firefox equivalent
From: dan_williams on 14 Jun 2006 18:26 I have the following test web page:- <html> <head><title>Test</title> <script language="Javascript"> <!-- function fnTR() { alert("TR"); } function fnSelect() { alert("Select"); } --> </script> </head> <body> <table width="300" height="50" border="1"> <tr onclick="javascript:fnTR();"> <td align="center"> <select onclick="javascript:fnSelect();"> <option>option 1</option> <option>option 2</option> </select> </td> </tr> </table> </body> </html> When clicking on my select dropdownlist, does anyone know how i can get my page to only execute the fnSelect function, and not the fnTR function aswell? In my real page, my functions perform other operations (i.e. fnTR highlights the selected row), but i've just put in alerts to demonstrate. Is it possible to do this without having to put onClick events in all my TD elements instead? Is there some sort of void function or return false; i could do? Or is it possible to add some functionality to my fnTR function that would check if I clicked on the dropdown box, and if so, not to perform the rest of the function? Thanks in advance for any suggestions Dan.
From: petermichaux on 14 Jun 2006 19:45 dan_williams(a)newcross-nursing.com wrote: > When clicking on my select dropdownlist, does anyone know how i can get > my page to only execute the fnSelect function, and not the fnTR > function aswell? > > In my real page, my functions perform other operations (i.e. fnTR > highlights the selected row), but i've just put in alerts to > demonstrate. > > Is it possible to do this without having to put onClick events in all > my TD elements instead? > Is there some sort of void function or return false; i could do? Or is > it possible to add some functionality to my fnTR function that would > check if I clicked on the dropdown box, and if so, not to perform the > rest of the function? > > Thanks in advance for any suggestions Hi Dan, It would be nice if there is some thing clean like a return false that would stop the tr handler from firing. I don't know if there is. Following from your last idea I just tested the following file <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Test</title> <script type='text/javascript'> var flag = false; function fnTR() { if (flag) { flag = false; } else { alert("TR"); } } function fnSelect() { flag = true; alert("Select"); } </script> </head> <body> <table width="300" height="50" border="1"> <tr onclick="fnTR();"> <td align="center"> <select onclick="fnSelect();"> <option>option 1</option> <option>option 2</option> </select> </td> </tr> </table> </body> </html> (Note no use of the deprecated language attribute or the <!-- --> hiding trick. I don't use "javascript:" and never have. Also I added a doctype.) I'm sure there are many ways to do this but if your situation is relatively simple this might be ok. Peter
From: RobG on 14 Jun 2006 23:35 petermichaux(a)gmail.com wrote: > dan_williams(a)newcross-nursing.com wrote: > > > When clicking on my select dropdownlist, does anyone know how i can get > > my page to only execute the fnSelect function, and not the fnTR > > function aswell? [...] > > It would be nice if there is some thing clean like a return false that > would stop the tr handler from firing. I don't know if there is. Yes, there is - you cancel event propagation to stop it bubbling up to objects higher in the DOM tree. Unfortunately IE and the W3C implemented different event models so it's a bit messy, but not to tough. If event handlers are coded in the HTML, pass 'event' to the function: <select onclick="fnSelect(event);"> Now W3C browsers will have a reference to the event that called the function. IE makes it a property of the window object, so in the function declaration do: function fnSelect( e ) { if ( !e ) { var e = window.event; } // can also do: var e = e || window.event; /* rest of function... */ } Now 'e' is a reference to the event that called the function in both event models. To cancel bubbling, IE uses: window.event.cancelBubble = true; W3C browsers use: e.stopPropagation() so now the function looks like: function fnSelect(e){ var e = e || window.event; e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); /* rest of function... */ } That will cancel bubbling for the function regardless of which element calls it, if you want it to bubble for other elements you may need to create a non-bubbling caller for elements whose events you don't want to bubble. Read more about events and event order at quirksmode: <URL:http://www.quirksmode.org/js/events_order.html> If adding event handlers from a function rather than in the HTML, things are a little different. A reference to the event is passed as the first argument to the function in the W3C model but not in IEs, so the function looks the same but the attachment process looks a little different. ie. to attach the function stick with: someEl.onclick = fnSelect; You don't have to do: someEl.onclick = function (){fnSelect(event);} or similar kludge. In the W3C model you can also specify whether the function fires in bubbling or capturing phases using addEventListener - it's all covered at quirksmode. [...] -- Rob
From: Richard Cornford on 15 Jun 2006 03:46 RobG wrote: <snip> > <select onclick="fnSelect(event);"> > > > Now W3C browsers will have a reference to the event that > called the function. IE makes it a property of the window > object, All browsers will pass a reference to the event object to the - fnSelect - function as an argument. This is due to the way in which the Identifier - event - is resolved in the context of the internally generated event handling function created by the browser from the value of the intrinsic event attribute. In W3C standard browsers that function has a formal parameter with the name 'event', so the Identifier resolves as the value of that parameter, the event object. The equivalent function generated by IE does not have a formal parameter so the Identifier - event - is not found at the top of the scope chain, instead IE goes on up- the scope chain until it gets to the global object where it finds (and resolves as) the global - event - property. > so in the function declaration do: > > function fnSelect( e ) > { > if ( !e ) { > var e = window.event; > } <snip> This is used in functions programmatically assigned as an event handler but not in functions called from an internally generated event handler where - event - is passed as an argument to that function. (It is, of course, harmless here as - e - will be false so - window.event - will never be evaluated.) Richard.
From: Richard Cornford on 15 Jun 2006 03:46
petermichaux(a)gmail.com wrote: <snip> > It would be nice if there is some thing clean like a > return false that would stop the tr handler from firing. > I don't know if there is. <snip> Understanding how events work in web browsers is fairly fundamental to programming a browser as a GUI. It is difficult to see how anyone learning to script web browsers could avoid learning this aspect of the task within a few months of starting to make the effort (with the exceptions of being VK or placing an unreasonable reliance on the internal details of a library/framework, the internals of which they did not understand). I hope you will remember the outcome of this thread next time you are considering directing people to particular sources of information, or recommending particular libraries/frameworks. If you really were qualified to judge you would not be expected to be deficient in the fundamentals of browser scripting. Richard. |