From: dan_williams on
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

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
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
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
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.


 |  Next  |  Last
Pages: 1 2 3 4
Prev: Ping
Next: onmouseleave Firefox equivalent