
November 17th, 2006, 03:45 PM
| | | Assigning dynamically declared event handlers to an object
Hello
I am new to creating objects in javascript, so please no flames about my
coding style. =) I am trying to create an object that will represent a "div"
element as a menu. I have written several methods that are working fine. The
problem is if I want to dynamically assign an event handler to the object,
the event handler is not called. What am I doing wrong? Below is a sample
HTML doc with everything in place.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Menu Manager Test</title>
<script>
function testMenu (id)
{
this.addAttributes = addProperty;
this.addEvents = addProperty;
this.id = (id || 'mainMenu');
this.element = document.getElementById(this.id);
if (this.element == null)
{
this.element = document.createElement("<div id='" + this.id +
"'>Some Text</div>");
document.body.appendChild(this.element);
}
this.element.style.display = 'none';
}
function addProperty(propertyName,keyValue)
{
// this is a standalone property like an event or innerHTML
if (propertyName.indexOf("=") >= 0)
{
for (var i=0;i<addProperty.arguments.length;i++)
{
var arg = addProperty.arguments[i].split("=");
this.element[arg[0]] = arg[1];
}
}
// this adds style elements
else
{
// args should be in the form of propertyname=value.
for (var i=1;i<addProperty.arguments.length;i++)
{
var arg = addProperty.arguments[i].split("=");
this.element[addProperty.arguments[0]][arg[0]] = arg[1];
}
}
}
// Sample implementation in the HTML page
// Test function to check for use.
function testFunc()
{alert("here in testFunc.");}
var menuObj;
function setMenu(id)
{
// Create a new menu
menuObj = new testMenu(id);
// Adding a style works
menuObj.addAttributes("style","width=200");
menuObj.addAttributes("style","backgroundColor=gre en");
menuObj.addAttributes("style","color=white");
menuObj.addAttributes("style","border=1px solid black");
menuObj.addAttributes("style","textAlign=center");
menuObj.addAttributes("style","position=absolute") ;
menuObj.addAttributes("style","zindex=1000");
menuObj.addAttributes("style","top=200");
menuObj.addAttributes("style","left=300");
menuObj.addAttributes("innerHTML=A ball of string");
menuObj.addAttributes("style","display=");
// Dynamically assigning an event handler does not work.
menuObj.addEvents("onmouseover=testFunc()");
menuObj.addEvents("onmouseout=testFunc()");
}
</script>
</head>
<body onLoad="setMenu('mainMenu');">
</body>
</html>
Peace in Christ -
Ron Goral | 
November 17th, 2006, 04:35 PM
| | | Re: Assigning dynamically declared event handlers to an object
Ron Goral wrote: Quote:
Hello
>
I am new to creating objects in javascript, so please no flames about my
coding style. =) I am trying to create an object that will represent a "div"
element as a menu. I have written several methods that are working fine. The
problem is if I want to dynamically assign an event handler to the object,
the event handler is not called. What am I doing wrong? Below is a sample
HTML doc with everything in place.
>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
>
<html>
>
<head>
<title>Menu Manager Test</title>
<script>
function testMenu (id)
{
this.addAttributes = addProperty;
this.addEvents = addProperty;
>
this.id = (id || 'mainMenu');
this.element = document.getElementById(this.id);
if (this.element == null)
{
this.element = document.createElement("<div id='" + this.id +
"'>Some Text</div>");
document.body.appendChild(this.element);
}
this.element.style.display = 'none';
}
>
function addProperty(propertyName,keyValue)
{
// this is a standalone property like an event or innerHTML
if (propertyName.indexOf("=") >= 0)
{
for (var i=0;i<addProperty.arguments.length;i++)
{
var arg = addProperty.arguments[i].split("=");
this.element[arg[0]] = arg[1];
}
}
// this adds style elements
else
{
// args should be in the form of propertyname=value.
for (var i=1;i<addProperty.arguments.length;i++)
{
var arg = addProperty.arguments[i].split("=");
this.element[addProperty.arguments[0]][arg[0]] = arg[1];
}
}
}
>
// Sample implementation in the HTML page
>
// Test function to check for use.
function testFunc()
{alert("here in testFunc.");}
>
var menuObj;
function setMenu(id)
{
// Create a new menu
menuObj = new testMenu(id);
// Adding a style works
menuObj.addAttributes("style","width=200");
menuObj.addAttributes("style","backgroundColor=gre en");
menuObj.addAttributes("style","color=white");
menuObj.addAttributes("style","border=1px solid black");
menuObj.addAttributes("style","textAlign=center");
menuObj.addAttributes("style","position=absolute") ;
menuObj.addAttributes("style","zindex=1000");
menuObj.addAttributes("style","top=200");
menuObj.addAttributes("style","left=300");
menuObj.addAttributes("innerHTML=A ball of string");
menuObj.addAttributes("style","display=");
// Dynamically assigning an event handler does not work.
menuObj.addEvents("onmouseover=testFunc()");
menuObj.addEvents("onmouseout=testFunc()");
}
</script>
</head>
>
<body onLoad="setMenu('mainMenu');">
</body>
</html>
>
Peace in Christ -
Ron Goral
| Hi Ron.
I am a complete novice, but I will give you my 2 cents anyway.
First of all, I would recommend you save yourself a little bit of
bandwidth, and consider using CSS as opposed to: Quote:
menuObj.addAttributes("style","width=200");
menuObj.addAttributes("style","backgroundColor=gre en");
menuObj.addAttributes("style","color=white");
menuObj.addAttributes("style","border=1px solid black");
menuObj.addAttributes("style","textAlign=center");
menuObj.addAttributes("style","position=absolute") ;
menuObj.addAttributes("style","zindex=1000");
menuObj.addAttributes("style","top=200");
menuObj.addAttributes("style","left=300");
| (This is not a flame, just a suggestion that might make life a little
easier).
As for the mouse events...
I can think of two mthods (which I cannot vouch for), that you may wish
to consider trying.
Firstly:
menuObj.addEvents("onmouseover=function() { testFunc(); }");
menuObj.addEvents("onmouseout=function() { testFunc(); }");
Secondly you could try:
menuObj.onmouseover=function() { testFunc(); }
menuObj.onmouseout=function() { testFunc(); }
Again, I can't stress enough how much of a beginner I am, but I think
it's worth a try.
I think the second one is most likely to work, but I can't be sure.
Please note, I have enclosed the function you wish to use within a
function(){} statement. I believe that if this isn't done, then the
function will be called as the script is loaded, and not actually
assigned to the event.
Best of luck.
Daz. | 
November 17th, 2006, 05:15 PM
| | | Re: Assigning dynamically declared event handlers to an object
"Daz" <cutenfuzzy@gmail.comwrote in message
news:1163782232.261146.268660@j44g2000cwa.googlegr oups.com... Quote:
Hi Ron.
>
I am a complete novice, but I will give you my 2 cents anyway.
>
First of all, I would recommend you save yourself a little bit of
bandwidth, and consider using CSS as opposed to: Quote:
menuObj.addAttributes("style","width=200");
menuObj.addAttributes("style","backgroundColor=gre en");
menuObj.addAttributes("style","color=white");
menuObj.addAttributes("style","border=1px solid black");
menuObj.addAttributes("style","textAlign=center");
menuObj.addAttributes("style","position=absolute") ;
menuObj.addAttributes("style","zindex=1000");
menuObj.addAttributes("style","top=200");
menuObj.addAttributes("style","left=300");
| (This is not a flame, just a suggestion that might make life a little
easier).
| I appreciate the suggestion. The idea of the addAttributes and addEvents
functions is to allow a person to define the menu in an HTML page without
accessing the .js file (where this will finally reside). Quote:
>
As for the mouse events...
>
I can think of two mthods (which I cannot vouch for), that you may wish
to consider trying.
Firstly:
menuObj.addEvents("onmouseover=function() { testFunc(); }");
menuObj.addEvents("onmouseout=function() { testFunc(); }");
| This ^ does not work. Quote:
Secondly you could try:
menuObj.onmouseover=function() { testFunc(); }
menuObj.onmouseout=function() { testFunc(); }
| This ^ does work.
Unfortunately, when the object code resides in a .js file, this is not going
to be feasible as I want the HTML author to be able to define the event in a
"<script></script>" block in his code. Quote:
Again, I can't stress enough how much of a beginner I am, but I think
it's worth a try.
>
I think the second one is most likely to work, but I can't be sure.
Please note, I have enclosed the function you wish to use within a
function(){} statement. I believe that if this isn't done, then the
function will be called as the script is loaded, and not actually
assigned to the event.
| This does indeed happen.
Thank you for the suggestions. I am further along the road of understanding,
however, I am certain there must be a way to do this. I can't be the first
or only person to ever want to do this sort of thing. Am I? ;P
Peace -
Ron | 
November 17th, 2006, 08:45 PM
| | | Re: Assigning dynamically declared event handlers to an object
"Daz" <cutenfuzzy@gmail.comwrote in message
news:1163782232.261146.268660@j44g2000cwa.googlegr oups.com... Quote:
>
As for the mouse events...
>
I can think of two mthods (which I cannot vouch for), that you may wish
to consider trying.
Firstly:
menuObj.addEvents("onmouseover=function() { testFunc(); }");
menuObj.addEvents("onmouseout=function() { testFunc(); }");
>
Secondly you could try:
menuObj.onmouseover=function() { testFunc(); }
menuObj.onmouseout=function() { testFunc(); }
>
Again, I can't stress enough how much of a beginner I am, but I think
it's worth a try.
>
I think the second one is most likely to work, but I can't be sure.
Please note, I have enclosed the function you wish to use within a
function(){} statement. I believe that if this isn't done, then the
function will be called as the script is loaded, and not actually
assigned to the event.
| eval() is the key. =)
The code considered the arguments being passed as strings. Of course, a
string cannot be executed, unless you use eval().
Using these modified calls:
menuObj.addEvents("event","onmouseover=function() { testFunc(); }");
menuObj.addEvents("event","onmouseout=function() { testFunc(); }");
And (greatly) modifying the addProperty function to be this:
function addProperty(propertyName,keyValue)
{
var type = (propertyName.indexOf("=") >= 0)?'standalone':propertyName;
for (var i=0;i<addProperty.arguments.length;i++)
{
var arg = addProperty.arguments[i].split("=");
// something like innerHTML
if (type == 'standalone'){this.element[arg[0]] = arg[1];}
// an event property
else if (type == 'event'){this.element[arg[0]] = eval("function(){"
+ arg[1] + "}");}
// style and other named attributes
else {this.element[addProperty.arguments[0]][arg[0]] = arg[1];}
}
}
Produces the desired results. =)
Thanks for the help Daz.
Peace -
Ron | 
November 17th, 2006, 10:25 PM
| | | Re: Assigning dynamically declared event handlers to an object
"Ron Goral" <news@uponthemountain.comwrote in message
news:qxp7h.6701$IR4.3191@newssvr25.news.prodigy.ne t...
This:
this.element[arg[0]] = eval("function(){"+arg[1]+"}");
Should be this:
this.element[arg[0]] = function(){eval(arg[1]);}; | 
November 18th, 2006, 01:35 AM
| | | Re: Assigning dynamically declared event handlers to an object
Ron Goral wrote: Quote:
"Ron Goral" <news@uponthemountain.comwrote in message
news:qxp7h.6701$IR4.3191@newssvr25.news.prodigy.ne t...
>
This:
>
this.element[arg[0]] = eval("function(){"+arg[1]+"}");
>
Should be this:
>
this.element[arg[0]] = function(){eval(arg[1]);};
| Yes indeed. Does that mean it's working now? | 
November 18th, 2006, 01:35 AM
| | | Re: Assigning dynamically declared event handlers to an object
Ron Goral wrote: Quote:
"Daz" <cutenfuzzy@gmail.comwrote in message
news:1163782232.261146.268660@j44g2000cwa.googlegr oups.com... Quote:
As for the mouse events...
I can think of two mthods (which I cannot vouch for), that you may wish
to consider trying.
Firstly:
menuObj.addEvents("onmouseover=function() { testFunc(); }");
menuObj.addEvents("onmouseout=function() { testFunc(); }");
Secondly you could try:
menuObj.onmouseover=function() { testFunc(); }
menuObj.onmouseout=function() { testFunc(); }
Again, I can't stress enough how much of a beginner I am, but I think
it's worth a try.
I think the second one is most likely to work, but I can't be sure.
Please note, I have enclosed the function you wish to use within a
function(){} statement. I believe that if this isn't done, then the
function will be called as the script is loaded, and not actually
assigned to the event.
| >
eval() is the key. =)
The code considered the arguments being passed as strings. Of course, a
string cannot be executed, unless you use eval().
>
Using these modified calls:
>
menuObj.addEvents("event","onmouseover=function() { testFunc(); }");
menuObj.addEvents("event","onmouseout=function() { testFunc(); }");
>
And (greatly) modifying the addProperty function to be this:
>
function addProperty(propertyName,keyValue)
{
var type = (propertyName.indexOf("=") >= 0)?'standalone':propertyName;
for (var i=0;i<addProperty.arguments.length;i++)
{
var arg = addProperty.arguments[i].split("=");
// something like innerHTML
if (type == 'standalone'){this.element[arg[0]] = arg[1];}
// an event property
else if (type == 'event'){this.element[arg[0]] = eval("function(){"
+ arg[1] + "}");}
// style and other named attributes
else {this.element[addProperty.arguments[0]][arg[0]] = arg[1];}
}
}
>
Produces the desired results. =)
>
Thanks for the help Daz.
Peace -
Ron
| Glad to have helped. Well done for figuring it out. :D | 
November 18th, 2006, 03:25 PM
| | | Re: Assigning dynamically declared event handlers to an object
I wish to share this routine (for which I must lookup the source...)
function addEvent(obj, evType, fn){
var res;
if (obj.addEventListener) {
obj.addEventListener(evType, fn, false);
res = true;
} else if (obj.attachEvent) {
var r = obj.attachEvent("on"+evType, fn);
res = r;
} else {
res = false;
}
return res;
}
obj is an HTMLElement; evType is a string like "click"; fn is a function
reference.
Let me elaborate on that last remark. This is a function definition:
function doWork(arg) {
alert(arg);
}
This is a corresponding function call:
doWork("'ello");
and this is the function reference:
doWork;
If you want to assign any function to a property like onclick, you must
assign the reference to the property:
thatDiv.onclick = doWork;
Alas, you cannot pass parameters to the function this way. Built-in
behaviour, nonetheless, is for the browser to pass the current event to
the function. Any event handling function should accept an event object
(unless you absolutely want to ignore the identity of the event, or do
not need its information). There is a little cross-browserity on it.
Microsofts browser does not pass the event, but has a global variable
'event' which carries the current event.
Lumping this together, your event handler function could look like
function doWork(e) {
if (!e) e = window.event;
// now you can be sure that e points to the current event object
// do whatever is necessary here
}
If you would put this:
thatDiv.onclick = doWork(argument);
doWork would be evaluated/executed, and its *result* is assigned to
onclick. Needless to say this will produce no effect when you actually
would click the element...
I have one other remark. When I create objects (classes, I like to call
them), I always include a private variable 'self' that is a copy of
'this'. It saves a lot of confusion as to what exactly this refers to,
when you are inside an object's functions.
function myObject() {
var self = this;
self.value = 0; // public member
// not really necessary here:
self.someMethod = functionname;
// nor here:
self.otherMethod = function(arg) {
// function body
self.value = 23; // 'this' would point to the function otherMethod!
}
}
This style may save you several "this.method is not a function" errors.
Ron Goral schreef: Quote:
Hello
>
I am new to creating objects in javascript, so please no flames about my
coding style. =) I am trying to create an object that will represent a "div"
element as a menu. I have written several methods that are working fine. The
problem is if I want to dynamically assign an event handler to the object,
the event handler is not called. What am I doing wrong? Below is a sample
HTML doc with everything in place.
>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
>
<html>
>
<head>
<title>Menu Manager Test</title>
<script>
function testMenu (id)
{
this.addAttributes = addProperty;
this.addEvents = addProperty;
>
this.id = (id || 'mainMenu');
this.element = document.getElementById(this.id);
if (this.element == null)
{
this.element = document.createElement("<div id='" + this.id +
"'>Some Text</div>");
document.body.appendChild(this.element);
}
this.element.style.display = 'none';
}
>
function addProperty(propertyName,keyValue)
{
// this is a standalone property like an event or innerHTML
if (propertyName.indexOf("=") >= 0)
{
for (var i=0;i<addProperty.arguments.length;i++)
{
var arg = addProperty.arguments[i].split("=");
this.element[arg[0]] = arg[1];
}
}
// this adds style elements
else
{
// args should be in the form of propertyname=value.
for (var i=1;i<addProperty.arguments.length;i++)
{
var arg = addProperty.arguments[i].split("=");
this.element[addProperty.arguments[0]][arg[0]] = arg[1];
}
}
}
>
// Sample implementation in the HTML page
>
// Test function to check for use.
function testFunc()
{alert("here in testFunc.");}
>
var menuObj;
function setMenu(id)
{
// Create a new menu
menuObj = new testMenu(id);
// Adding a style works
menuObj.addAttributes("style","width=200");
menuObj.addAttributes("style","backgroundColor=gre en");
menuObj.addAttributes("style","color=white");
menuObj.addAttributes("style","border=1px solid black");
menuObj.addAttributes("style","textAlign=center");
menuObj.addAttributes("style","position=absolute") ;
menuObj.addAttributes("style","zindex=1000");
menuObj.addAttributes("style","top=200");
menuObj.addAttributes("style","left=300");
menuObj.addAttributes("innerHTML=A ball of string");
menuObj.addAttributes("style","display=");
// Dynamically assigning an event handler does not work.
menuObj.addEvents("onmouseover=testFunc()");
menuObj.addEvents("onmouseout=testFunc()");
}
</script>
</head>
>
<body onLoad="setMenu('mainMenu');">
</body>
</html>
>
Peace in Christ -
Ron Goral
>
>
| --
Bas Cost Budde
Holland www.heuveltop.nl/BasCB/msac_index.html | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 205,248 network members.
|