Passing parameters to event handler

P

Pavils Jurjans

Hallo,

I have been programming for restricted environments where Internet Explorer
is a standard, so I haven't stumbled upon this problem until now, when I
need to write a DOM-compatible code.

The question is about best practices for passing parameters to an event
function.

I have, say, the following HTML:

<div onclick="myEventHandler()">Here's some text</div>

and here's the event handler function:

function myEventHandler(evt) {
evt = (evt) ? evt : ((event) ? event : null); // to get single interface
to the IE event object or the DOM event object.
// Now must handle the event
}

In the example case, the event handler is written directly in the html code,
or the strings is outputed with document.write or element.innerHTML is
assigned. However, in more general way, my application framework allows also
to snap that event to most any tag and still the handling should be exatly
as defined. There are no multiple handler functions, the behaviour is
determined by the function that took care for attaching the event. That
means, I *have* to pass some parameters with the handler function call. In
IE that ie easy, as I have no requirement to provide a single argument to
the handler function that is filled with event object. I can freely write
onclick="myHandler(123)" and it works fine. Now, I see some approaches to
handle this parameter passing problem. One is assigning the parameters to
some global variable and then accessed from within the event handler
function:

onclick="parms={a:1, b:2}; myHandler()"

function myHandler() {
alert(parms.a + "; " + parms.b);
}

it's ugly, since I dont like that function refers to external global
variable parm, but it works. However I am not sure if the values of
parameters are persistent while the event handler and all the function call
chain is processed.

So, maybe there is some standard approach practised among ECMAscript
developers?

Thanks,


-Pavils Jurjans
 
Y

Yep

The question is about best practices for passing parameters to an event
function.
<div onclick="myEventHandler()">Here's some text</div>
function myEventHandler(evt) {
evt = (evt) ? evt : ((event) ? event : null); // to get single interface
to the IE event object or the DOM event object.

Better to use the following in such situations:
evt=evt||window.event;
Javascript's "||" operator is much more powerful than generally
assumed by (non-js) programmers - Ecma refers.


In the onclick attribute (which, to js, is an anonymous function) the
event object is available as "event", so you can just pass it to the
internal handler (in IE you'll pass the global event object, which is
fine).

<div onclick="func(event,'World')">Hello...?</div>
<script type="text/javascript">
function func(evt, s){
alert(s+" (from "+(evt.srcElement||evt.target).nodeName+")");
}
</script>


That's the easy way; just for fun, here's another way (not really
recommendable, but much more enjoyable):

<div onclick="func2('World')">Hello...?</div>
<script type="text/javascript">
function func2(s){
var evt = window.event || function(cx) {
if(typeof Event!="undefined" && cx){
for(var ii=0; ii<cx.arguments.length; ii++)
if(cx.arguments[ii] instanceof Event)
return cx.arguments[ii];
return arguments.callee(cx.caller);
}
return null;
}(arguments.callee.caller);

alert(s+" (from "+(evt.srcElement||evt.target).nodeName+")");
}
</script>


Regards,
Yep.
 
P

Pavils Jurjans

Hallo Yep,

The first method is the one I was looking for, I didn't know that in the
scope of event handler attribute the "event" object is available in non-IE
platforms.

The other method certainly is certainly charming :) The syntax used kinda
tells what kind of 'compact javascript' lover you are ;)

What regards the use of "logical OR" operation for determining the "first
available non-false/null/undefined item in the chain, it's a nice trick. I,
also being lover of compactness, appreciate this hint, however it may reduce
the readability of my code for other programmers. It's a surprise for me
that the operands of "logical OR" operation are not internally converted to
booleans prior to executing the operation. I am not sure how standard is
this behaviour, and I am cautious if this isn't a hack that may not be
present in some JavaScript environment that strictly follows the ECMA262
guidelines. In the book what I use for referring JavaScript queries
(O'Reillys' JavaScript the definitive Guide 3rd ed.), there is no hint about
the use of "logical OR" for returning non-boolean variable types. How sure
one can be it's the feature here to stay?

-- Pavils Jurjans
 
R

Richard Cornford

What regards the use of "logical OR" operation for determining
the "first available non-false/null/undefined item in the chain,
it's a nice trick. I, also being lover of compactness, appreciate
this hint, however it may reduce the readability of my code for
other programmers.

You would let the limitations of another language restrict your
JavaScript? Would those other programmers put up with their
non-JavaScript code being limited to only include structures that made
sense in JavaScript?
It's a surprise for me that the operands of "logical OR" operation
are not internally converted to booleans prior to executing the
operation.

They are, at least the left hand operand is, but that internal boolean
value is never the result of the expression.
I am not sure how standard is this behaviour, and I am cautious
if this isn't a hack that may not be present in some JavaScript
environment that strictly follows the ECMA262 guidelines.

<quote cite="ECMA 262 3rd edition Section 11.11">

The production LogicalORExpression : LogicalORExpression ||
LogicalANDExpression is evaluated as follows:

1. Evaluate LogicalORExpression.
2. Call GetValue(Result(1)).
3. Call ToBoolean(Result(2)).
4. If Result(3) is true, return Result(2).
5. Evaluate LogicalANDExpression.
6. Call GetValue(Result(5)).
7. Return Result(6).

</quote>

Notice that ECMA 262 requires that the result of the expression be the
result of a call to the internal GetValue function and not the result of
the call to ToBoolean on which the decision about which operand to
return is made.
In the book what I use for referring JavaScript queries (O'Reillys'
JavaScript the definitive Guide 3rd ed.), there is no hint about
the use of "logical OR" for returning non-boolean variable types.

JavaScript the definitive Guide might be the best book on JavaScript
available but it still does not cover much of the really interesting
stuff. (Does it mention closures?)
How sure one can be it's the feature here to stay?

It is ECMA 262 Specified, so it is here to stay.

Richard.
 
P

Pavils Jurjans

Hallo Richard,

Your reference to ECMA spec set's it straight and safe
JavaScript the definitive Guide might be the best book on JavaScript
available but it still does not cover much of the really interesting
stuff. (Does it mention closures?)

I was somewhat mistaken claiming that it doesn't provide hint on that
specific functionality. It actually does, but doesn't provide explicit
examples, so I missed it. Yes, the book covers closures, and does it
in quite detailed manner. It doesn't focus too much on OO-patterns,
but then again it's not that JavaScript oriented topic, but rather
than general programming one.

Rgds,

-- Pavils Jurjans
 
R

Richard Cornford

Pavils Jurjans said:
The first method is the one I was looking for, I didn't know
that in the scope of event handler attribute the "event"
object is available in non-IE platforms.
<snip>

It might be worth explaining why - event -, as an identifier, works in
both Netscape/Gecko and IE even though they handle the referencing of
event objects differently.

It works like this, given the example HTML:-

<input onblur="doSomething(this, event);"
type=""text""
name="anyName">

- the browser takes the string that is provided as the value for the
onblur attribute and uses that string as the function body for an
anonymous function that it creates (internally) as an onblur event
handling method for the input element. On Netscape browsers it is the
equivalent of doing this in JavaScript:-

document.forms['aForm'].elements['anyName'].onblur = function(event){
doSomething(this, event);
}

- notice that the internally created function has a parameter with the
identifier - event - . IE produces an anonymous function like:-

document.forms['aForm'].elements['anyName'].onblur = function(){
doSomething(this, event);
}

- with no specified parameter. The practical result is that any use of
the identifier - event - within the string assigned to an event handling
attribute in HTML will refer to the event object because in
Netscape/Gecko browsers it refers to the automatically generated and
named function parameter - event - and on IE it is resolved as the
global - event - object.

The same is not true of event handling functions defined with JavaScript
and then assigned to event handling properties (or with
addEventListener) as if those functions are defined with - event - as
the identifier for their first parameter the use of the identifier -
event - within the function body can only refer to that parameter,
though the IE global event object could still be more explicitly
referenced with - window.event _. But it is normal to give the first
parameter of such a function a different identifier and then use the
logical OR construct to normalise it to refer to which ever event object
was available.

Richard.
 
R

Richard Cornford

... . It doesn't focus too much on OO-patterns,
but then again it's not that JavaScript oriented
topic, but rather than general programming one.

If you are interested in JavaScript OO it would be worth having a look
at what Douglas Crockford has to say on the subject (particularly
inheritance and emulating private instance members on JS objects).

<URL: http://www.crockford.com/ >

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top