473,384 Members | 1,854 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,384 software developers and data experts.

How to add extra action to onclick event ?

abs
My element:
<span onclick="alert('test')" id="mySpan">test</span>

Let's say that I don't know what is in this span's onclick event. Is it
possible to add another action to this element's onclick event ? I've tried
something like this:

oncl = document.getElementById('mySpan').onclick
oncl = oncl + '\n;alert(\'added\')'
document.getElementById('mySpan').onclick = oncl

And after this operation there'e no reaction to clicking on the <span>.
Anybody knows how to fix it ?

Best regards,
ABS


Jul 23 '05 #1
17 4838
alu

"abs" <no****@wp.pl> wrote in message news:d7**********@inews.gazeta.pl...
My element:
<span onclick="alert('test')" id="mySpan">test</span>

Let's say that I don't know what is in this span's onclick event. Is it
possible to add another action to this element's onclick event ? I've tried something like this:

oncl = document.getElementById('mySpan').onclick
oncl = oncl + '\n;alert(\'added\')'
document.getElementById('mySpan').onclick = oncl

And after this operation there'e no reaction to clicking on the <span>.
Anybody knows how to fix it ?

Best regards,
ABS

I'm probably misunderstanding the problem, but it would seem easier
to set onclick to a function, then add lines to the -function- dynamically.

<scr ipt>
function mySpanClicked(){
alert("test");
}
</scr ipt>

<span onclick="mySpanClicked()" id="mySpan">test</span>

<scr ipt>
.... script to add to mySpanClicked()
</scr ipt>

-alu
Jul 23 '05 #2
You cant just add another action to the onClick event, but you may find
this handy....

<span onclick="alert('test');alert('second function')"
id="mySpan">test</span>

This will now call the 2 actions one after the other. note the
semi-colon in there after the first event.

You can repeat that more to add extra actions.

Best Regards,
Sandfordc

Jul 23 '05 #3
On 26/05/2005 20:32, abs wrote:
My element:
<span onclick="alert('test')" id="mySpan">test</span>

Let's say that I don't know what is in this span's onclick event. Is it
possible to add another action to this element's onclick event ?
The code at the end of this post is a very generic way of adding and
removing listeners from an element, much in the same way as the
addEventListener method.

Though the code looks daunting, a lot of it is internal. For basic
usage, you need only three methods:

DispatcherFactory.createDispatcher()

This creates and returns a dispatcher object. Each dispatcher
maintains a list of listeners that are associated with a type
of event. When the dispatcher is attached to an element, it
forwards all events of this type to the listeners it manages.

The other two important methods are members of the dispatcher objects
returned by createDispatcher.

Dispatcher.add(listener)

This method adds a function to the internal list. Simple.
Dispatcher.attach(element, type)

This methods associates the dispatcher with a particular
event type, such as the click event, and a particular element.
If a listener already exists on that element for that type (an
onclick attribute, for example), it will be added to the
internal list before the dispatcher is attached.

So, given:

<span id="mySpan" onclick="alert('original');">Test</span>

and a reference to that element:

var element = document.getElementById('mySpan');

you can add a new function with:

var dispatcher = DispatcherFactory.createDispatcher();

dispatcher.add(function() {
alert('added');
});
dispatcher.attach(element, 'onclick');

You can call add and attach in any order, and you can add listeners at
any time. You can also attach the same dispatcher to several different
elements with different types, though I doubt you'll have any use for that.

The other two methods you can use are again dispatcher members.

Dispatcher.remove(listener)

This searches for the given function. If it exists within the
list, it's discarded.
Dispatcher.detach(element, type)

This removes the dispatcher and all of its listeners of the
given type from the element.
There are simpler solutions, but they aren't as flexible. It's
incredibly late now, so someone else will have to continue with those
alternatives.
oncl = document.getElementById('mySpan').onclick
oncl = oncl + '\n;alert(\'added\')'
document.getElementById('mySpan').onclick = oncl


There's a misconception here: the onclick property isn't a string. When
a user agent parses attributes like onclick in HTML, it converts the
code to a function. So, it's not simply a matter of added more code. The
dispatcher object below allows you to manage several functions on one
property.

Do ask if you have any questions.

Mike
Parts of the code below can be removed. If you won't be removing
listeners, you can eliminate the two remove methods (in Node and
createDispatcher), the detachDispatcher function, and the line:

Dispatcher.detach = detachDispatcher;

The code at the very end emulates the call method that should exist on
all functions. JScript versions prior to 5.5 (and so usually IE versions
prior to 5.5) don't include this method so a substitute needs to be
included. The dispatcher code only needs case 1 within the switch
statement, so you could remove the other clauses. They were included to
make the substitute more useful.

var DispatcherFactory = (function(global) {
function Node(data) {
var next = null;

this.fire = function(element, event) {
var performDefault = next
? next.fire(element, event)
: true;

return data.call(element, event) && performDefault;
};

this.add = function(listener) {
if(data == listener) {return;}

if(next) {
next.add(listener);
} else {
next = new Node(listener);
}
};
this.remove = function(listener) {
if(data == listener) {
return next;
} else if(next) {
next = next.remove(listener);
}
return this;
};
}

function attachDispatcher(element, type) {
var listener = element[type];

if(('function' == typeof listener)
&& (this.constructor != listener.constructor))
{
this.add(listener);
}
element[type] = this;
}
function detachDispatcher(element, type) {
if(this == element[type]) {
element[type] = null;
}
}

return {
createDispatcher : function() {
var list = null;

function Dispatcher(event) {
return list
? list.fire(this, event || global.event)
: true;
}
}
Dispatcher.constructor = this;

Dispatcher.add = function(listener) {
if(list) {
list.add(listener);
} else {
list = new Node(listener);
}
};
Dispatcher.remove = function(listener) {
if(list) {
list = list.remove(listener);
}
};

Dispatcher.attach = attachDispatcher;
Dispatcher.detach = detachDispatcher;
}
};
})(this);

if('function' != typeof Function.prototype.call) {
Function.prototype.call = function(object) {
var property = '__call', result, undef;

while('undefined' != typeof object[property]) {
property = '__' + property;
}
object[property] = this;

switch(arguments.length - 1) {
case 0:
result = object[property]();
break;
case 1:
result = object[property](arguments[1]);
break;
case 2:
result = object[property](arguments[1], arguments[2]);
break;
case 3:
result = object[property](arguments[1], arguments[2],
arguments[3]);
break;
case 4:
result = object[property](arguments[1], arguments[2],
arguments[3], arguments[4]);
break;
case 5:
result = object[property](arguments[1], arguments[2],
arguments[3], arguments[4], arguments[5]);
break;
default: alert('Too many arguments!');
}
object[property] = undef;

return result;
};
}

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #4
On 27/05/2005 03:26, Michael Winter wrote:

[snip]
function Dispatcher(event) {
return list
? list.fire(this, event || global.event)
: true;
}

^
I don't know where that closing brace came from, but it shouldn't be there.

I'll make the disclaimer now: this code is untested, and will remain so
until I wake up tomorrow. I don't think there are any more problems, but
I'm too tired to make any kind of guarantee.

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #5
abs
Michael Winter wrote:
I'll make the disclaimer now: this code is untested, and will remain
so until I wake up tomorrow. I don't think there are any more
problems, but I'm too tired to make any kind of guarantee.


First, thank you so much for your post containing so lot of knowledge.
I've got one problem with that: when I call:

dispatcher.add(function() {
alert('added');
});

Firefox, throws an error: 'dispatcher has no properties'. I'm trying to fix
it by myself, but until now I couldn't see any mistakes in the code.

Best regards,
ABS
Jul 23 '05 #6
abs
alu wrote:
I'm probably misunderstanding the problem, but it would seem easier
to set onclick to a function, then add lines to the -function-
dynamically.


Thanks, but it's impossible. This is a part of bigger project and it has to
be universal, I don't even know the name of the function of onclick.

Regards,
ABS
Jul 23 '05 #7
abs
And another question: will I be able to pass the parameter to added function
?

ABS
Jul 23 '05 #8
VK
var success = (window.addEventListener)?
someObject.addEventListener('click',
functionPointer, false) :
someObject.attachEvent('onclick',
functionPointer);

You can add/attach any amount of functions to any object. Three points
to pay attention to:

1. With multiple event handlers each event handler will be called in a
random order (so you don't know which one will be called 1st, 2nd, 3rd,
n-th)

2. attachEvent in IE requires function pointer as its argument, so you
cannot use anonymous function declaration instead. You can bypass it by
doing:
var newFun = new Function(...);
someObject.attachEvent('onclick', newFun);

3. in IE event names are always "onevent" (starts with "on"). In FF a
semi-philologic approach is chosen, so
obj.onevent = (with "on") but addEventListener('event'...) (without
"on") Not really a problem but easy to mistype.

If you really need to call handlers in a fixed sequence (kinda
pointless because native JavaScript does not have synchronized methods)
you may use a function wrapper:
var newFun = new Function("method1; method2; method3;...");
var success = (window.addEventListener)?
someObject.addEventListener('click', newFun,
false) :
someObject.attachEvent('onclick', newFun);

Jul 23 '05 #9
VK wrote:
var success = (window.addEventListener)?
someObject.addEventListener('click',
The W3C events DOM - addEventListener - method is specified as a
property of Node objects. The - window - is not a Node object and so is
not specified as having such a property, and in some environments
supporting the events DOM the window does not have such a method. The
obviously correct test to use in this context is the test that has a
one-to-one relationship with the action to be taken; -
(someObj.addEventListener)?someObject.addEventList ener -.
functionPointer, false) :
someObject.attachEvent('onclick',
Not all browsers that do not implement a - window.addEventListener -
method implement an - attachEvent - method on elements. Indeed I can
only think of two that do. In the absence of such a method this code
would error-out with the call to a non-existent method, which is pretty
poor scripting.

<snip> 2. attachEvent in IE requires function pointer as its
argument, so you cannot use anonymous function declaration
instead.
There is no such thing as an 'anonymous function declaration'; the
function name Identifier is not optional in a function declaration.
You can bypass it by doing:
var newFun = new Function(...);
someObject.attachEvent('onclick', newFun);

<snip>

Bypass what? A function object is a function object regardless of how it
is created.

Richard.
Jul 23 '05 #10
VK
> Bypass what?

I thought you couldn't do like obj.attachEvent('onclick',
function(){alert('Click!');})
But my test case appeared to be broken, it works, so sorry.

Jul 23 '05 #11
VK
I guess

foo = (arr[i].addEventListener)?
arr[i].addEventListener('click', extra, false) :
arr[i].attachEvent('onclick', extra);

(where 'extra' is your function) would be enough in any context and no
problem with passing argument.

You have to remember that intrinsic handlers (<elm onevent="...") have
priority over programmed ones, so the function call goes like this:
1. intrinsic handlers
2. programmed handlers in random order (actually, this is the same
"organized disorder" as with key/value pairs in hash)

If you want to extend functionality based on the content of the
intrinsic handler, you may write an "EventStealer" though it has more
relation to hacking rather than to development:

....
var objRef = e.target || event.srcElement;
var evtType = (e.type)? e.type : event.type;
var funRef = objRef['on'+evtType];
alert("On " + evtType + " this "+ objRef.tagName + " does this:\n\n" +
funRef.toString();)
objRef['on'+evtType] = null;
alert("And now it does not!");

The code above is useless as it is, but you may study the function body
using RegExp and recompile it based on the study results.

Jul 23 '05 #12
On 27/05/2005 07:17, abs wrote:

The problem with the code as posted is that createDispatcher doesn't
actually return anything. I apologise.

After the line:

Dispatcher.detach = detachDispatcher;

add:

return Dispatcher;

After that it 'works', but I'll be happier once I perform more tests.
And another question: will I be able to pass the parameter to added function
?


I'm afraid not, but that's how the event model itself works. The
function you pass to the add method will always receive one argument:
the event object. The difference between this and using the event
attributes in HTML is that the user agent creates this outer function
for you. However, you can easily call other functions within the
listener (just like alert in the example), passing any arguments you like.

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #13
abs
Thank you guys for your posts. You helped me much.

ABS
Jul 23 '05 #14
VK wrote:
I guess

foo = (arr[i].addEventListener)?
arr[i].addEventListener('click', extra, false) :
arr[i].attachEvent('onclick', extra);

(where 'extra' is your function) would be enough in any
context and no problem with passing argument.
Except on browsers that support neither mechanism, where the call to the
non-existent - attachEvent - method errors and kicks the code out of
execution.

<snip> var objRef = e.target || event.srcElement;
var evtType = (e.type)? e.type : event.type;
If - e - was not defined evaluating the expression - e.type - would
produce an error (again). It makes more sense to normalise the event
object once with - e = e || window.event -(and the like) and then act
only on that normalised event object.
var funRef = objRef['on'+evtType];
alert("On " + evtType + " this "+ objRef.tagName +
" does this:\n\n" + funRef.toString();)
objRef['on'+evtType] = null;
alert("And now it does not!");

The code above is useless as it is,
Absolutly.
but you may study the function body using
RegExp and recompile it based on the study results.


The - toString - method of functions is specified as producing an
"implementation dependent" string. That string does not necessarily
correspond with the function's source code, and cannot necessarily be
re-interpreted as a functionally equivalent function. I.E. This strategy
should be expected to fail, and it certainly will in known existing
environments under some circumstances.

Richard.
Jul 23 '05 #15
On 27/05/2005 12:20, Richard Cornford wrote:

[snip]
The - toString - method of functions is specified as producing an
"implementation dependent" string. That string does not necessarily
correspond with the function's source code,
Maybe, but I'd think not. After the specification states that "An
implementation-dependent representation of the function is returned", it
goes on to say that "This representation has the syntax of a
FunctionDeclaration."

My interpretation is that the returned value should correspond with the
source code, but that the "placement of white space, line terminators,
and semicolons within the representation string is
implementation-dependent."

Of course, what should happen and what does happen in practice isn't
always the same.
and cannot necessarily be re-interpreted as a functionally equivalent
function.


Very true. There may be no way to reconstruct the scope chain, which may
render the function completely useless.

[snip]

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #16
Michael Winter wrote:
On 27/05/2005 12:20, Richard Cornford wrote: <snip>
The - toString - method of functions is specified as
producing an "implementation dependent" string. That
string does not necessarily correspond with the
function's source code,

<snip> it goes on to say that "This representation has the syntax
of a FunctionDeclaration." <snip> Of course, what should happen and what does happen
in practice isn't always the same.

<snip>

Yes, regular expression literals within function bodies have proved a
recurrent problem in this context because they are independently
interpreted into regular expression objects. It is not unusual to find a
regular expression object in a toString-ed function coming out as
[Object], or something similar. Which is a syntactically fine expression
in a regular expression literal context (being an array literal with one
element referring to the Object constructor), but will certainly not
produce the original functionality.

Chopping up function body strings and re-assembling the results has been
tired, but all that I have observed trying it (at least those that
actually test their code more than superficially) seem to rapidly
abandon the idea in favour of accumulating function references in the
type of code you presented.

Richard.
Jul 23 '05 #17
VK wrote:
Bypass what?


I thought you couldn't do like obj.attachEvent('onclick',
function(){alert('Click!');})
But my test case appeared to be broken, it works, so sorry.


No. You both can and cannot use this. It depends on the JScript version
available on the client whether function expressions are considered a
syntax error or not. With new IEs, chances are high that it works.
PointedEars
--
Let us not judge others because of their religion, color or nationality.
We are all just human beings living together on this planet. (poehoe.de)
Jul 23 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Matthew | last post by:
Hi, how can I create a <A HREF'ed> image that, with an onclick event will cause the cursor to jump into a particularly assigned text form input field?
17
by: Mike Gratee | last post by:
Is it possible to use JavaScript to cause the browser to click a link on a page and have the browser act exactly like the user had clicked on the link directly? In other words, I need to...
2
by: Vinita Sharma | last post by:
Hi All, I have a strange problem. I have 2 text boxes and a button in my form. There is a function called on onchange event of the first text box. There is another function called on onclick...
3
by: f1crazed | last post by:
Hello, I am wanting to fire the onClick event of button1 by pressing button2. Does anyone have a clue if this is even posible? If so PLEASE HELP!! Thanks.
4
by: Roland | last post by:
I was wondering, what happens when you have an onclick event and an error occurs in it: In an <a> element: onclick="zoomFullExtent(); return false;" I know that there is an error happening...
5
by: Stuart Shay | last post by:
Hello All I am working on ASP.NET 1.1 Custom Pager that allows a User to Enter a Number in a TextBox and go to the page selected. Since the OnClick Event does not work in ASP.NET 1.1 for a...
3
by: Michael_R_Banks | last post by:
I'm trying to dynamically build a table that allows users to remove rows when they click a corresponding button. For some reason, whenever I add the button to the table, it never fires the onclick...
7
by: Moses | last post by:
Hi Everybody, I have a problem with onClick event which works in FF and does not work in IE, Here I have giving the details Please help. I am creating a <aTag. dom_obj =...
6
by: Nathan Sokalski | last post by:
I have a DataList which contains several LinkButtons, which are used to select a category in my application. I want the currently selected category to use a different CSS class. Here is an example...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.