By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,598 Members | 1,894 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,598 IT Pros & Developers. It's quick & easy.

Assigning same onclick dynamically and statically

P: n/a

I have a function whose parameter is a reference the element that called it:

function someFunction(el)
{
...
}

The function is assigned to the onclick event of some elements in the
HTML source:

<input ... onclick="someFunction(this);" ...>

and dynamically to others:

elRef.onclick = someFunction;
When someFunction() is called from the statically-assigned onclick, el
is a reference to the element. But when it has been added dynamically,
el will be either undefined (IE) or 'event' (Mozilla et al).

To assign the right value to el, I can test if el exists and if it does,
whether its constructor is some type of HTML element or 'Event'. But IE
doesn't support the constructor property for elements (or have I just
not found it yet?) nor does it understand 'Event' the way Mozilla does.

Anyhow, the following test does the job:

function someFunction(el)
{
var el=(!el || (el.constructor && Event == el.constructor))? this : el;
...

If el is undefined:
- have IE dynamically added event, el is assigned the value of 'this'

If el is defined
- have IE statically added event, el is assigned the value of el
OR
- have Mozilla:
- if el.constructor is Event, have dynamically added event,
el is assigned the value of this
- if el.constructor is not Event, have statically added event,
el is assigned the value of el
It works, but seems long winded and dependent on the vagaries of the two
event models. As a result, I've been using:

var el = (el && el.nodeName)? el : this;

This seems much simpler - if el is defined and has a nodeName, use it.
Otherwise, use this.

Rather than detecting if the function was passed a reference to 'event'
or not, it sees if an element was passed. It works and assigns a
reference to the element whether called from the statically or
dynamically attached function.

Is that reasonable logic, or should the first method be used? Or is
there a better way of doing what I'm after?
Some sample code:
<input type="button" value="Replace onclick" onclick="
replaceOnclick(this);
alert('Old onclick replaced');
">

<script type="text/javascript">
function replaceOnclick(el)
{
// Short version
var el = (el && el.nodeName)? el : this;

// Long version (wrapped for posting)
// var el = ( !el || (el.constructor
&& Event == el.constructor) )? this : el;

el.onclick = replaceOnclick;
alert( el.nodeName + ': new onclick');
}
</script>


--
Rob
Oct 17 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a


RobG wrote:

<input ... onclick="someFunction(this);" ...>

and dynamically to others:

elRef.onclick = someFunction;


You need
elRef.onclick = function (evt) {
someFunction(this);
};
then to have the same as that onclick attribute in the HTML markup creates.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Oct 17 '05 #2

P: n/a
VK

RobG wrote:
I have a function whose parameter is a reference the element that called it:

function someFunction(el)
{
...
}

The function is assigned to the onclick event of some elements in the
HTML source:

<input ... onclick="someFunction(this);" ...>

and dynamically to others:

elRef.onclick = someFunction;
When someFunction() is called from the statically-assigned onclick, el
is a reference to the element. But when it has been added dynamically,
el will be either undefined (IE) or 'event' (Mozilla et al).

To assign the right value to el, I can test if el exists and if it does,
whether its constructor is some type of HTML element or 'Event'. But IE
doesn't support the constructor property for elements (or have I just
not found it yet?) nor does it understand 'Event' the way Mozilla does.


Another (clearer??) way:

function someFunction() {
var el = someFunction.arguments[1] ||
someFunction.arguments[0].target;
...
}

<input ... onclick="someFunction(null,this);" ...>

elRef.onclick = someFunction;

I say that Mozilla/3W way demostrates its big flaw here: it leads to
the left/right arguments' shift in functions depending on how they are
being called: from the program stream or by event listeners. That's a
pain for distributed libraries.

Oct 18 '05 #3

P: n/a
VK wrote:
RobG wrote:
I have a function whose parameter is a reference the element that called it:

function someFunction(el)
{
...
}

The function is assigned to the onclick event of some elements in the
HTML source:

<input ... onclick="someFunction(this);" ...>

and dynamically to others:

elRef.onclick = someFunction;
When someFunction() is called from the statically-assigned onclick, el
is a reference to the element. But when it has been added dynamically,
el will be either undefined (IE) or 'event' (Mozilla et al).

To assign the right value to el, I can test if el exists and if it does,
whether its constructor is some type of HTML element or 'Event'. But IE
doesn't support the constructor property for elements (or have I just
not found it yet?) nor does it understand 'Event' the way Mozilla does.

Another (clearer??) way:

function someFunction() {
var el = someFunction.arguments[1] ||
someFunction.arguments[0].target;
...
}

<input ... onclick="someFunction(null,this);" ...>

elRef.onclick = someFunction;


I don't think that's an improvement - it introduces peculiarities at
both ends.

I say that Mozilla/3W way demostrates its big flaw here: it leads to
the left/right arguments' shift in functions depending on how they are
being called: from the program stream or by event listeners. That's a
pain for distributed libraries.


The 'flaw', if there is one, is that there are two models - I can't
comment on whether one is better than the other.

Martin's suggestion is fine, I've used it frequently but it seems a bit
of a hack to use an anonymous function to call another function (I guess
views on that differ).

Incidentally, nice you see you're back contributing :-)
--
Rob
Oct 18 '05 #4

P: n/a
VK
> VK wrote:
... it leads to the left/right arguments' shift in functions depending on...
Correcting myself as a wrong wording and explanation: there is not any
*shift* here. The first argument in each function (3W model) is
reserved for the Event data. You can use it for other purposes but it
will be like sitting on someone place ready to leave at any moment. As
soon as your function is called by an event listener, the first
argument will contain the Event data no matter what kind of argument
your function was really expecting. We may call it "a different
approach" or "an unforseen oops of the chosen model", it's really a
question of preferences :-)
So wrappers from anonymous functions (despite their semi-ugliness)
would be a choice I guess.

the following test does the job:
function someFunction(el)
{
var el=(!el || (el.constructor && Event == el.constructor))? this : el;
There must be some surrounding code missing because here (and in the
other variant) you assign window object to el in IE case (this ==
window.self within named function body). That doesn't seem your aim.

Incidentally, nice you see you're back contributing :-)

;-)

Oct 18 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.