473,781 Members | 2,491 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

passing the string-name of the function to addEvent

hi,

I would like to separate my javascript completely from my xhtml. in the
end there should be only
<script type="text/javascript" src="javalib.js "></script>
in the head-tag to my javascript.

Because I want to use some ajax-requests and other javascript-functions
on my xhtml, I need to dynamically add event handlers to any possible
dom-elements. All solutions I found so fare are for specific, pre-known
dom-elements: like 'all <imgof a certain <span>-class get an
onmouseover event handler'. But I need a function, which runs onload of
the window and dynamically determines, which dom-elments need an event
handler and which ones don't.
So I guessed the best way would be to traverse the whole dom-tree
looking for certain id-attributes, which would indicate the browser,
that the according dom-element (having the certain id-attribute) needs
to have an event added.
Therefore I defined my id-attributes with a pattern like eg. <span
id="onclick_hel loworld_param1_ param2"></spanwhat means, that the
value of the id attribute first needs to provide the name of an event
handler, this way javascript can determine that this dom-element is an
element, which needs to have an event-handler. Then javascript can
parse the value of the id-attribute with the function split('_');
With the above example this results in an array containing:
[0] 'onclick' //the event-handler
[1] 'helloworld' //the function to be called
[2] 'param1'
... ..
[n] 'paramn' //the parameters for the function to be called.

so far all good, but now I'm stuck with the following problem: I got
the name of the function as a String and don't know how to make
javascript understand that this string points to an actual function,
like:

function helloworld(para m1, param2, ... , paramn){
alert(param1);
}

I guess it all comes down to the following question: I'm trying to use
the 'famous' function addEvent(). What do I need to do just having name
of fn as a string, and want to pass the parameters to fn too?

//this is what I tried the latest, but it obviously does not work...
n = some dom-element;
eve = 'click';
var newfunct = new Function(param1 , param2);
newfunct.name = 'helloworld';
addEvent(n, eve, newfunct, false);

function addEvent(elm, evType, fn, useCapture) {
if (elm.addEventLi stener) {
elm.addEventLis tener(evType, fn, useCapture);
return true;
}
else if (elm.attachEven t) {
var r = elm.attachEvent ('on' + evType, fn);
return r;
}
else {
elm['on' + evType] = fn;
}
}

thanks for any help or other ideas to solve the problem of dynamically
add event handlers to any possible dom-elments.

s

Dec 14 '06 #1
4 2384
simon said the following on 12/14/2006 5:51 PM:
hi,

I would like to separate my javascript completely from my xhtml. in the
end there should be only
<script type="text/javascript" src="javalib.js "></script>
in the head-tag to my javascript.

Because I want to use some ajax-requests and other javascript-functions
on my xhtml, I need to dynamically add event handlers to any possible
dom-elements. All solutions I found so fare are for specific, pre-known
dom-elements: like 'all <imgof a certain <span>-class get an
onmouseover event handler'. But I need a function, which runs onload of
the window and dynamically determines, which dom-elments need an event
handler and which ones don't.
So I guessed the best way would be to traverse the whole dom-tree
looking for certain id-attributes, which would indicate the browser,
that the according dom-element (having the certain id-attribute) needs
to have an event added.
Therefore I defined my id-attributes with a pattern like eg. <span
id="onclick_hel loworld_param1_ param2"></spanwhat means, that the
value of the id attribute first needs to provide the name of an event
handler, this way javascript can determine that this dom-element is an
element, which needs to have an event-handler. Then javascript can
parse the value of the id-attribute with the function split('_');
With the above example this results in an array containing:
[0] 'onclick' //the event-handler
[1] 'helloworld' //the function to be called
[2] 'param1'
.. ..
[n] 'paramn' //the parameters for the function to be called.
theArray = attr.split('_') ;

Set up a case/switch for the different handlers. Then in each case block
you deal with that:

elemRef.onclick =window[theArray[1]](theArray[2],theArray[3]);

All global functions are properties of the window object in any decently
implemented browser (that includes IE as well).

--
Randy
Chance Favors The Prepared Mind
comp.lang.javas cript FAQ - http://jibbering.com/faq
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Dec 15 '06 #2
simon wrote:
hi,

I would like to separate my javascript completely from my xhtml. in the
end there should be only
<script type="text/javascript" src="javalib.js "></script>
in the head-tag to my javascript.
[...]
Therefore I defined my id-attributes with a pattern like eg. <span
id="onclick_hel loworld_param1_ param2"></spanwhat means, that the
I think you need to prefix that with a real id to guarantee unique IDs.
Also consider putting the parameter part in the class attribute so you
don't trash your IDs this way.
value of the id attribute first needs to provide the name of an event
handler, this way javascript can determine that this dom-element is an
element, which needs to have an event-handler. Then javascript can
parse the value of the id-attribute with the function split('_');
With the above example this results in an array containing:
[0] 'onclick' //the event-handler
[1] 'helloworld' //the function to be called
[2] 'param1'
.. ..
[n] 'paramn' //the parameters for the function to be called.

so far all good, but now I'm stuck with the following problem: I got
the name of the function as a String and don't know how to make
javascript understand that this string points to an actual function,
like:

function helloworld(para m1, param2, ... , paramn){
alert(param1);
}

Given that param[1] is the string 'helloworld' then:

window[param[1]]();

will call the helloworld function. Consider name spacing your
functions.

I guess it all comes down to the following question: I'm trying to use
the 'famous' function addEvent(). What do I need to do just having name
of fn as a string, and want to pass the parameters to fn too?

//this is what I tried the latest, but it obviously does not work...
n = some dom-element;
eve = 'click';
var newfunct = new Function(param1 , param2);
Ditch that, new Function() is considered only marginally better than
eval.
newfunct.name = 'helloworld';
var newfunct = window[param[1]];
addEvent(n, eve, newfunct, false);
And how do you pass the parameters? I'd suggest that you use shift()
to get the first few parameters, then pass the remainder of the
parameter array to the function using apply, see below.

The apply method (which uses an array as the set of arguments) also
lets you set the value of the function's this keyword appropriately (IE
and Gecko event models differ here, apply makes them consistent).

e.g.

<script type="text/javascript">

function processId(el){
var params = el.className.sp lit('_');
if (params.length 1){
var evt = params.shift();
var fn = params.shift();
addEvent(el, evt,
function(){wind ow[fn].apply(el, params)}, false);
}
}

function addEvent(elm, evType, fn, useCapture) {
if (elm.addEventLi stener) {
elm.addEventLis tener(evType, fn, useCapture);
return true;
}
else if (elm.attachEven t) {
var r = elm.attachEvent ('on' + evType, fn);
return r;
}
else {
elm['on' + evType] = fn;
}
}

window.onload = function(){
processId(docum ent.getElementB yId('xx'));
processId(docum ent.getElementB yId('yy'));
}

function hi(args){
alert('id: ' + this.id
+ '\nparams: ' + args);
}

</script>
<div id="xx" class="click_hi _x1_x2">xx</div>
<div id="yy" class="click_hi _y1_y2">yy</div>
Notes:

The parameters are passed as strings, if you want them to be something
else, you'll have to deal with that in the processId() function.

If you want to have real class names in the class attribute, you'll
have to include a scheme to find your parameter class name in amongst
the other class names.

You may be tempted to use a getElementsByCl assName function to find
your special elements and process their special class attribute.

Consider removing the extra attribute values when you've finished with
them if you have other processing of the class attribute to do. It
might also help the browser if there is less junk in the attribute.
--
Rob

Dec 15 '06 #3
thanks for your help!

in the meanwhile I could arrange my code to work by myself. I will
check it with your suggestions.
to be sure that the id remains unique i will add a incremental value to
it at its end.
the following has been tested on safari, firefox and iex. works for
ajax-requests too just recalling traverseTags(aj axresponse).
if you just can shake your head and get bad headaches upon this
solution don't hesitate to let me know!! ;)

<script type="text/javascript">

this.onload = init;

function sali (e){
alert('done' + this.params.toS tring());
}

function hoi(e){
alert('done' + this.params.toS tring());
}

//returns function for a function string
function getFunction(fun ctionstr){
if(functionstr == 'sali'){
return sali;//function sali
}
else if(functionstr == 'hoi'){
return hoi;//function hoi
}
else{
return false;
}
//etc.
}

function init(){
traverseTags(do cument);
}
//if some browser does not know the Node object
if (!window.Node) {
var Node = { // If there is no Node object, define one
ELEMENT_NODE: 1, // with the following properties and values.
ATTRIBUTE_NODE: 2, // Note that these are HTML node types only.
TEXT_NODE: 3, // For XML-specific nodes, you need to add
COMMENT_NODE: 8, // other constants here.
DOCUMENT_NODE: 9,
DOCUMENT_FRAGME NT_NODE: 11
}
}

//stores all possible events
var arrEvents = new Array('onclick' , 'ondblclick', 'onmousedown',
'onmouseup', 'onmouseover', 'onmousemove', 'onmouseout', 'onkeypress',
'onkeydown', 'onkeyup');

//array function to check for a certain value in an array. call:
array.contains( value)
Array.prototype .contains = function(value) {
for (var i = 0; i < this.length; i++) {
if (this[i] == value) return true;
}
return false;
}

//traversing the tags i thereby could assign the function name:
function traverseTags(n) {
var children = n.childNodes;
if(n.nodeType == Node.ELEMENT_NO DE && n.attributes.le ngth 0){
for(var i = 0; i < n.attributes.le ngth; i++){

if(n.attributes[i].nodeName == 'id' &&
isEventTag(n.at tributes[i].nodeValue)){// && n.hasAttributes () not iex
var call = new
callerObject(is EventTag(n.attr ibutes[i].nodeValue));
var eve = call.getEvent() ;

var funct = call.getFunctio n();

var params = call.getParams( );

addEvent(n, eve, getFunction(fun ct), false);//needs to be an
addEvent function which contains the this reference for iex.
n.params = params;
break;
}
}
}

for(var i=0; i < children.length ; i++) { // Loop through the
children
traverseTags(ch ildren[i]);
}
}
//checks if the id attribute is a event
function isEventTag(idAt tribute){
var spliter = idAttribute.spl it('_');//spliter is the array with all
parameters form the id attribute: e.g.
onclick_somefun ction_sometag_p aram1_param2_pa ram3
if(arrEvents.co ntains(spliter[0])) return spliter;
return false;
}


//parses the array
function callerObject(ca llerArray){
var event = callerArray[0];//der event
var funct = callerArray[1];//die function
var callback_obj = null;
var paramArray = new Array();
for(var i = 0; i < callerArray.len gth-2; i++){
paramArray[i] = callerArray[i+2];
}

this.getFunctio n = function(){
return funct;// Function(funct + '(' + paramArray.toSt ring() +
');');
}

this.getParams = function(){
return paramArray;
}

this.getEvent = function(){
return getEventOfStrin g(event);
}

function getEventOfStrin g(eventstr){//private
if(eventstr == 'onclick'){
return 'click';
}
else if(eventstr == 'ondblclick'){
return 'dblclick';
}
else if(eventstr == 'onmousedown'){
return 'mousedown';
}
else if(eventstr == 'onmouseup'){
return 'mouseup';
}
else if(eventstr == 'onmouseover'){
return 'mouseover';
}
else if(eventstr == 'onmousemove'){
return 'mousemove';
}
else if(eventstr == 'onkeypress'){
return 'keypress';
}
else if(eventstr == 'onkeydown'){
return 'keydown';
}
else if(eventstr == 'onkeyup'){
return 'keyup';
}
else{
return false;
}
}
}

// written by Dean Edwards, 2005
// with input from Tino Zijdel, Matthias Miller, Diego Perini

// http://dean.edwards.name/weblog/2005/10/add-event/

function addEvent(elemen t, type, handler) {
if (element.addEve ntListener) {
element.addEven tListener(type, handler, false);
} else {
// assign each event handler a unique ID
if (!handler.$$gui d) handler.$$guid = addEvent.guid++ ;
// create a hash table of event types for the element
if (!element.event s) element.events = {};
// create a hash table of event handlers for each element/event pair
var handlers = element.events[type];
if (!handlers) {
handlers = element.events[type] = {};
// store the existing event handler (if there is one)
if (element["on" + type]) {
handlers[0] = element["on" + type];
}
}
// store the event handler in the hash table
handlers[handler.$$guid] = handler;
// assign a global event handler to do all the work
element["on" + type] = handleEvent;
}
};
// a counter used to create unique IDs
addEvent.guid = 1;

function removeEvent(ele ment, type, handler) {
if (element.remove EventListener) {
element.removeE ventListener(ty pe, handler, false);
} else {
// delete the event handler from the hash table
if (element.events && element.events[type]) {
delete element.events[type][handler.$$guid];
}
}
};

function handleEvent(eve nt) {
var returnValue = true;
// grab the event object (IE uses a global event object)
event = event || fixEvent(((this .ownerDocument || this.document ||
this).parentWin dow || window).event);
// get a reference to the hash table of event handlers
var handlers = this.events[event.type];
// execute each event handler
for (var i in handlers) {
this.$$handleEv ent = handlers[i];
if (this.$$handleE vent(event) === false) {
returnValue = false;
}
}
return returnValue;
};

function fixEvent(event) {
// add W3C standard event methods
event.preventDe fault = fixEvent.preven tDefault;
event.stopPropa gation = fixEvent.stopPr opagation;
return event;
};
fixEvent.preven tDefault = function() {
this.returnValu e = false;
};
fixEvent.stopPr opagation = function() {
this.cancelBubb le = true;
};

</script>
<a href="index1.ht ml" id="onclick_hoi _index2.html">c lick me to
replace1</a><br/>
<a href="index2.ht ml" id="onclick_sal i_index.html_2" >click me to
replace2</a><br/>
<a href="index3.ht ml" id="onclick_sal i_index.html_3" >click me to
replace3</a><br/>
<a href="index4.ht ml" id="onclick_sal i_index.html_4" >click me to
replace4</a><br/>
<a href="index5.ht ml" id="onclick_sal i_index.html_5" >click me to
replace5</a><br/>

Dec 15 '06 #4
In comp.lang.javas cript message
<11************ **********@80g2 000cwy.googlegr oups.com>, Fri, 15 Dec 2006
06:09:41, simon <si************ *@gmail.comwrot e:
function getEventOfStrin g(eventstr){//private
if(eventstr == 'onclick'){
return 'click';
}
else if(eventstr == 'ondblclick'){
return 'dblclick';
}
else if(eventstr == 'onmousedown'){
return 'mousedown';
}
else if(eventstr == 'onmouseup'){
return 'mouseup';
}
else if(eventstr == 'onmouseover'){
return 'mouseover';
}
else if(eventstr == 'onmousemove'){
return 'mousemove';
}
else if(eventstr == 'onkeypress'){
return 'keypress';
}
else if(eventstr == 'onkeydown'){
return 'keydown';
}
else if(eventstr == 'onkeyup'){
return 'keyup';
}
else{
return false;
}
}
If all good eventstr start with "on" and the rest must be returned, else
false, then

function XX(es) { var T
return ( ( (T = es.replace(/^on/, "")) ) != es ) && T }

could be used. But it accepts anything after "on" (though it could
easily be modified to accept only letters, and only 5-9 of those.

It's a good idea to read the newsgroup and its FAQ. See below.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v6.05 IE 6
<URL:http://www.jibbering.c om/faq/ A FAQ for news:comp.lang. javascript.
<URL:http://www.merlyn.demo n.co.uk/js-index.htmjscr maths, dates, sources.
<URL:http://www.merlyn.demo n.co.uk/TP/BP/Delphi/jscr/&c, FAQ items, links.
Dec 15 '06 #5

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

Similar topics

9
2299
by: Just Me | last post by:
PARAFORMAT2 is a structure that SendMessage will return stuff in. Is the "ref" correct or since only a pointer is being passed should it be by value? Suppose I was passing data rather then receiving it, would that change the answer to the above?
3
1813
by: Steve B. | last post by:
Can't pass an array from one class to another. Steve Class Form1 { public string dGridTitles = new string {"xyz",,,,,}; public string getdGridTitles() {
13
2798
by: Maxim | last post by:
Hi! A have a string variable (which is a reference type). Now I define my Method like that: void MakeFullName(string sNamePrivate) { sNamePrivate+="Gates" }
6
3258
by: Scott Zabolotzky | last post by:
I'm trying to pass a custom object back and forth between forms. This custom object is pulled into the app using an external reference to an assembly DLL that was given to me by a co-worker. A query-string flag is used to indicate to the page whether it should instantiate a new instance of the object or access an existing instance from the calling page. On the both pages I have a property of the page which is an instance of this custom...
22
25605
by: Arne | last post by:
How do I pass a dataset to a webservices? I need to submit a shoppingcart from a pocket PC to a webservice. What is the right datatype? II have tried dataset as a datatype, but I can't get it to compile. <WebMethod()> _ Public Function VerifySku(ByVal skus As XmlDataDocument) As DataSet Test program : Dim cartSet As DataSet cartSet = ws.VerifySku(cartSet)
2
1303
by: Thomas Beyerlein | last post by:
Hello, I am trying to build a UI and I need the user to go though about 4 forms making decisions and then passing the decision to the next form. Finally on the last form I need all the answers to open the next and final form, which there are 16 different ways to go. So I thought by putting the decisions in an array, and passing it to each form. I get this error-: Value of type '1-dimensional array of String' cannot be converted to...
10
3475
by: Stan | last post by:
There are two ways to pass structured data to a web service: xml === <Order OrderId="123" OrderAmount="234" /> or class =====
61
3161
by: academic | last post by:
When I declare a reference variable I initialize it to Nothing. Now I'm wondering if that best for String variables - is "" better? With Nothing I assume no memory is set aside nor GC'ed But with "" it is - correct? The system seems to handle a null the same as "".
3
1988
by: James Robertson | last post by:
I am new to the ASP and VB thing so be kind. Question I have is that I have created an ASPX web site to use as an E-Mail page. But I want to use this for a lot of users. Can I create the link on the WEB site to mail to passing a variable from the WEB site to the ASPX web site to E-Mail to? Hope I explained this correctly. This is a response from another group. There was no way for you to know it, but this is a classic asp newsgroup....
11
6169
by: =?Utf-8?B?U3VqZWV0?= | last post by:
If there are long strings (like 1MB or 2MB) is it more performant to pass those by ref to methods or by value?
0
10308
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10143
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10076
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9939
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6729
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5375
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5507
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4040
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2870
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.