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

adding a new function to an event handler...

P: n/a
I'm writing some code which does one thing when onreadystatechange
occurs, e.g.

handle.onreadystatechange = function() { blah(handle,other_params) };

....but sometimes I need to add another, so it becomes:

handle.onreadystatechange = function() {
whatever_was_previously_defined(whatever);some_oth er_function(handle) };

How can I easily add some_other_function(handle) without knowing
whatever_was_previously_defined(whatever)?

Note it's important that the functions are executed in this order.

Thanks,

Ian
Jul 23 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Ian Richardson wrote:
I'm writing some code which does one thing when onreadystatechange
occurs, e.g.

handle.onreadystatechange = function() { blah(handle,other_params) };

...but sometimes I need to add another, so it becomes:

handle.onreadystatechange = function() {
whatever_was_previously_defined(whatever);some_oth er_function(handle) };
How can I easily add some_other_function(handle) without knowing
whatever_was_previously_defined(whatever)?

Note it's important that the functions are executed in this order.

Thanks,

Ian


var oldhandler = handle.onreadystatechange;
handle.onreadystatechange = function()
{
if (null != oldhandler)
{
oldhandler();
}
some_other_functio*n(handle);
}

Jul 23 '05 #2

P: n/a
RobB wrote:

[snip]
var oldhandler = handle.onreadystatechange;
handle.onreadystatechange = function()
{
if (null != oldhandler)
{
oldhandler();
}
some_other_functio*n(handle);
}


That would be fine as long as oldhandler doesn't use the this operator
to refer to handle. In such cases, either make oldhandler a property
of handle, or change the existing call to

oldhandler.call(this);

The former is probably preferable due to Microsoft's late
implementation of the call method.

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #3

P: n/a
Michael Winter wrote:
RobB wrote:

[snip]
var oldhandler = handle.onreadystatechange;
handle.onreadystatechange = function()
{
if (null != oldhandler)
{
oldhandler();
}
some_other_functio*n(handle);
}
That would be fine as long as oldhandler doesn't use the this

operator to refer to handle. In such cases, either make oldhandler a property
of handle, or change the existing call to

oldhandler.call(this);

The former is probably preferable due to Microsoft's late
implementation of the call method.

Mike


Mike: thanks.

Like this?

var oldhandler = handle.onreadystatechange;
handle.onreadystatechange = function()
{
if (null != oldhandler)
{
handle.oldhandler = oldhandler;
handle.oldhandler();
}
some_other_functio*n(handle);
}

Jul 23 '05 #4

P: n/a
RobB wrote:

[snip]
Mike: thanks.
You're welcome.
Like this?


[snip]

Yes, though you may as well avoid the global.

handle.oldHandler = handle.onreadystatechange;
handle.onreadystatechange = function() {
if(handle.oldHandler) {handle.oldHandler();}
someOtherFunction(this);
};

The added benefit of this approach is that allows this to be applied
to as many objects as necessary.

[snip]

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #5

P: n/a
"Ian Richardson" <za*****@chaos.org.uk> wrote in message
news:hR*****************@newsfe5-gui.ntli.net...
I'm writing some code which does one thing when onreadystatechange
occurs, e.g.

handle.onreadystatechange = function() { blah(handle,other_params) };

...but sometimes I need to add another, so it becomes:

handle.onreadystatechange = function() {
whatever_was_previously_defined(whatever);some_oth er_function(handle)
};

How can I easily add some_other_function(handle) without knowing
whatever_was_previously_defined(whatever)?

Note it's important that the functions are executed in this order.


The already provided suggestions are all workable, but I'd like to throw
my solution into the ring:

function addDelegate(element, elementEvent, delegate)
{
// multi-cast delegates are attached to the element as an Array;
// ie - element['onclickDelegates'], element['onfocusDelegates'],
etc
var elementDelegates = elementEvent + 'Delegates';

if (element[elementDelegates])
{
// there are already multi-cast delegates for this element
// and this event; add this delegate
element[elementDelegates].push(delegate);
}
else
{
// no multi-cast delegates for this element for this event;
// create a multi-cast delegate list for the element
element[elementDelegates] = [];

if (element[elementEvent])
{
// this element has a delegate for this event already;
// preserve the delegate and append it to the list of
// multi-cast delegates
element[elementEvent + 'Delegate'] = element[elementEvent];
element[elementDelegates].push(element[elementEvent]);
}

// append the new delegate to the list of multi-cast delegates
element[elementDelegates].push(delegate);

// change the event to a function which will fire all
// multi-cast delegates
element[elementEvent] = (function() {
return function()
{
for (var ii = 0; ii < this[elementDelegates].length;
++ii)
{
this[elementDelegates][ii].call(this);
}
}
})();
}
} // addDelegate()

function removeDelegate(element, elementEvent, delegate)
{
// multi-cast delegates are attached to the element as an Array;
// ie - element['onclickDelegates'], element['onfocusDelegates'],
etc
var elementDelegates = elementEvent + 'Delegates';

if (element[elementDelegates])
{
// multi-cast delegates for this element were found

var delegatesRemoved = 0;

if (elementEvent == delegate)
{
// SPECIAL CASE: when the delegate to be removed is the same
// String as the event, attempt to remove the preserved
// original delegate for this element for this event;
// this is done because the original delegate may be an
// anonymous function built from the original HTML;
// ie - <input ... onclick="...">
delegate = element[elementEvent + 'Delegate'];
}

// iterate through the multi-cast delegates; when a matching
// one is found, remove it from the list
var ii = 0;
while (ii < element[elementDelegates].length)
{
if (element[elementDelegates][ii] == delegate)
{
element[elementDelegates].splice(ii, 1);
++delegatesRemoved;
}
else
{
++ii;
}
}

// return the number of multi-cast delegates removed
return delegatesRemoved;
}

// no multi-cast delegates were found for this element; return
// something to give the caller this information
return -1;
} // removeDelegate()

The above functions allow you to add as many delegates (event handlers)
as you want to an event. Note that I have only ever used it with form
elements, I'm assuming it will work with host objects.

In your case, you'd use:

addDelegate(handle, 'onreadystatechange', function() { ... });

Note that if you declare the delegate anonymously as shown above, you
will be unable to remove it later. To avoid this problem, declare the
delegate concretely:

function myDelegate() {
removeDelegate(this, 'onreadystatechange', myDelegate);
// do stuff
}
addDelegate(handle, 'onreadystatechange', myDelegate);

By the way, I've also never tested the above, it just occurred to me
that you should be able to remove a delegate from an object from within
the delegate.

My solution suffers from the fact that it relies on a method not added
until JScript 5.6, so it may not be suitable for the general use
Internet.

--
Grant Wagner <gw*****@agricoreunited.com>
comp.lang.javascript FAQ - http://jibbering.com/faq
Jul 23 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.