Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsGeneralPHPASPPerlColdFusionFlashHTML, CSS, ScriptsBrowsers

Webmaster Forum / HTML, CSS, Scripts / JavaScript / May 2005



Tip: Looking for answers? Try searching our database.

Dynamically building objects

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
sirsean@gmail.com - 29 May 2005 22:38 GMT
Hi all. I'm trying to dynamically build menus and objects after my page
loads. Data is stored in an XML file and is parsed at runtime into
Javascript objects. At the moment, I'm working on creating menu items
from these objects. The parsing works fine (using Sarissa), and Firefox
builds the menu no problem. IE, however, does not. The functionality of
the menu will be a single onclick event. It seems that Firefox allows
me to set the onclick event handler for something built dynamically,
but IE won't.

Does anyone have any information on this, or a possible alternate
solution? Thanks.
Richard Cornford - 29 May 2005 23:01 GMT
> Hi all. I'm trying to dynamically build menus and objects
> after my page loads. Data is stored in an XML file and is
> parsed at runtime into Javascript objects.

That is a bad idea. XML is sub-optimal as a vehicle for transmitting
data to an ECMAScript enabled client. JSON is much better as the
ECMAScript interpreter can parse that directly to JS objects.

> At the moment, I'm working on creating menu items from
> these objects. The parsing works fine (using Sarissa), and
> Firefox builds the menu no problem. IE, however, does not. The
> functionality of the menu will be a single onclick event. It
> seems that Firefox allows me to set the onclick event handler
> for something built dynamically, but IE won't.

IE provides two independent mechanisms for attaching event handlers to
dynamically created DOM elements.

> Does anyone have any information on this, or a possible alternate
> solution? Thanks.

Stop using the - setAttribute - method to attach event handlers as when
that works it is just an unspecified side effect. Attach event handlers
by assigning function references to the event handling properties of the
DOM elements, or use a branching W3C - addEventListener -/ IE -
attachEvent - approach.

Richard.
sirsean@gmail.com - 29 May 2005 23:48 GMT
Interesting. I hadn't thought of using addEventListener. However, I
have now tried it, and am using the "click" event for these menu items,
but it does not work. It fires off the event immediately (the function
gets called as the page loads), which it shouldn't do, and then
clicking on the item does nothing. Is there some trick to using
addEventListener? Haven't tried attachEvent yet for IE, and won't until
I get it working in Firefox first.

As for XML and JSON, I'm afraid I have to use XML for this particular
project. It's a contract with another software company, and they want
to use XML.

Thanks.
Richard Cornford - 30 May 2005 01:04 GMT
> Interesting. I hadn't thought of using addEventListener.
> However, I have now tried it, and am using the "click"
[quoted text clipped - 3 lines]
> then clicking on the item does nothing. Is there some
> trick to using addEventListener?

You are using a CallExpression for the assignment where you should be
using a MemberExpression.

(
CallExpression production (ECMA 262 3rd edition; section 11.2.3):-

CallExpression : MemberExpression Arguments

MemberExpression production (ECMA 262 3rd edition; section 11.2):-

MemberExpression:
   PrimaryExpression
   FunctionExpression
   MemberExpression [ Expression ]
   MemberExpression . Identifier
   new MemberExpression Arguments
)

> Haven't tried attachEvent yet for IE, and won't
> until I get it working in Firefox first.
>
> As for XML and JSON, I'm afraid I have to use XML for this
> particular project. It's a contract with another software
> company, and they want to use XML.

A pity you couldn't involve anyone with pertinent technical skills in
the negotiation of the contract. That is a very risky approach to
contracts because you may find yourself contracted to do the impossible,
and so unable to deliver.

Richard.
sirsean@gmail.com - 30 May 2005 01:34 GMT
Well, I've fixed the problem I was just having with addEventListener
(that being that I was attempting, foolishly, to test it out using
"alert" and it wasn't working because I had to write a separate
function that is called when the event is fired).

Unfortunately, now the problem I've come across is that when the event
is fired, it is passed exactly one argument, which is an object (do you
perchance know what that object is and what's in it?). I need to know
the id of the menu item that is clicked, so I tried to use this.id in
the event function. This works fine in Firefox, but in IE, this.id is
apparently undefined. What is some way to get around that?

And I've read into JSON a bit, and it doesn't seem that it's perfect
for every scenario. We get the data out of a database (that we the
developers know nothing about) in the form of an XML file that is
validated against a well-formed XML Schema definition. JSON doesn't do
that, nor can the database in question easily output data in JSON
format. The parsing is either on the server or the client, and we don't
get to know anything about the server in this case. So XML it is.

Thanks,
SEAN
Richard Cornford - 30 May 2005 02:19 GMT
> Well, I've fixed the problem I was just having with
> addEventListener (that being that I was attempting,
> foolishly, to test it out using "alert" and it wasn't
> working because I had to write a separate
> function that is called when the event is fired).

At some point it might occur to you that if you post some code people
might have some idea of what you are talking about, and you might get
responses a little more specific to the situation.

> Unfortunately, now the problem I've come across is that
> when the event is fired, it is passed exactly one argument,
> which is an object (do you perchance know what that object
> is and what's in it?).

It is the event object.

> I need to know the id of the menu item that is clicked,
> so I tried to use this.id in the event function.

Please don't tell us that you are going to use the ID with
getElementById to look up a reference to the Element.

> This works fine in Firefox, but in IE,
> this.id is apparently undefined.
<snip>

In what sense do you mean 'in IE'? IE doesn't support -
addEventListener - at all.

> What is some way to get around that?

Almost certainly.

I bet the best solution will be my first suggestion of assigning a
function reference to the onclick property of the dynamically created
DOM element. That gives (near [1]) identical behaviour on the two
browsers you appear to be interested in (and many others) .

Richard.

[1] The difference being that Mozilla passes the event object to the
event handler, while IE makes it available as a global variable.
sirsean@gmail.com - 30 May 2005 03:04 GMT
Maybe you should have read the rest of the thread before you got pissy.
The whole issue was that your suggestion of using the DOM onclick
property *doesn't work*. So I was looking for alternate ways to do it.

Here's some code:
...
var a = document.createElement("A");
a.setAttribute("onclick", "alert(1);");
...

That works fine in Mozilla, but not in IE. The function is never
called. It was suggested that I try using addEventListener (attachEvent
in IE, look up a few posts, that's what I "meant" by "in IE").

That explanation should catch you up. Too bad I had to waste my time
explaining that when you could have read it. If you want to tell me the
same thing, point me to where on this page it says a viable alternate
solution to this problem. Please. Do it. No?

Fine, then I'll tell you why I need the ID. It's not to use
getElementById to look up a reference, because that not only is
completely unnecessary, but also pretty dumb. Part of the ID is a
number that I need to extract and use. It's of the form "button_XXX"
where XXX is some number. I simply extract the XXX out and have the
number I need. "In IE" it doesn't work ("in IE" meaning "using Internet
Explorer as my web browser"), because this.id has no value in the
function called by addEventListener/attachEvent. Mozilla handles it
fine.

And drop the JSON vs XML crap, it's not relevant.
Richard Cornford - 30 May 2005 03:31 GMT
> Maybe you should have read the rest of the thread before
> you got pissy. The whole issue was that your suggestion
> of using the DOM onclick property *doesn't work*.

Yes it does. It is the most widely supported and reliable approach
available.

> So I was looking for alternate ways
> to do it.
[quoted text clipped - 4 lines]
> a.setAttribute("onclick", "alert(1);");
> ...
<snip>
> Too bad I had to waste my time explaining that when
> you could have read it. If you want to tell me the
> same thing, point me to where on this page

This page?

> it says a viable
> alternate solution to this problem.

Perhaps you should go back and re-read the thread.

> Please. Do it. No?
<snip>

Make me.  ;-)

Richard.
RobG - 30 May 2005 06:04 GMT
> Maybe you should have read the rest of the thread before you got pissy.
> The whole issue was that your suggestion of using the DOM onclick
[quoted text clipped - 5 lines]
> a.setAttribute("onclick", "alert(1);");
> ...

   var a = document.createElement("A");
   a.onclick = function() {alert('1');};
   ...

 Will do the trick, or:

   function sayHi(el) {
     alert( ( el.id )? el.id : 'I have no ID' );
   }

   ...
   var a = document.createElement('A');
   a.onclick = function () {sayHi(this)} ;
   ...

 or:

   function sayHi(e) {
     e = e || window.event;
     var el = e.target || e.srcElement;
     alert( ( el.id )? el.id : 'I have no ID' );
   }

   ...
   var a = document.createElement('A');
   a.onclick = sayHi;
   ...

 Please advise which of the above does not work in both IE and any other
 common UA?

[...]

Signature

Rob

Richard Cornford - 30 May 2005 13:31 GMT
<snip>
>     function sayHi(e) {
>       e = e || window.event;
[quoted text clipped - 6 lines]
>     a.onclick = sayHi;
>     ...
<snip>

As functions assigned to event handling properties of DOM elements are
executed as methods of those DOM elements there is no need to worry
about the event's target in order to get a reference back to the DOM
element to which the handler is attached. That reference will always be
available as the - this - keyword. Hence preferring this approach over
the IE attachEvent method, where the handler is executed in the global
context and so special handling is required for IE.

Richard.
RobG - 30 May 2005 14:02 GMT
> <snip>
>
[quoted text clipped - 18 lines]
> the IE attachEvent method, where the handler is executed in the global
> context and so special handling is required for IE.

 In other words...

    function sayHi() {
      alert( ( this.id )? this.id : 'I have no ID' );
    }

    ...
    var a = document.createElement('A');
    a.onclick = sayHi;
    ...

 will suffice. Thanks.

Signature

Rob

Richard Cornford - 30 May 2005 14:45 GMT
<snip>
>> As functions assigned to event handling properties ...
<snip>
>   In other words...
>
[quoted text clipped - 8 lines]
>
>   will suffice. Thanks.

Yes. But there is still the question of what the ID is going to be used
for. It is a bit depressing to recall the number of times I have seen
people reading - this.id - and then using the ID to look up a reference
to the element with - document.getelementById -, without ever seeing
that - this - was (and must be) the value they wanted in the first
place.

Richard.
sirsean@gmail.com - 31 May 2005 01:15 GMT
Actually that question is now moot. I only needed to be able to get the
id because I needed the number in it. Rob's post helped tremendously,
and now I can use the DOM onclick property (who would have thought
wrapping it in function(){} would have done the trick?). Therefore, the
id isn't needed any more and everything is working swimmingly.

Thanks for the help, all.
SEAN
Matt Kruse - 30 May 2005 00:34 GMT
> That is a bad idea.

That is a ridiculously unjustified conclusion.

> XML is sub-optimal as a vehicle for transmitting
> data to an ECMAScript enabled client.

Perhaps if you define sub-optimal by only considering the size of the data
delivered.

Other factors which may contribute to picking the "optimal" solution
include:
1) Ease of interacting with an existing system
2) Ease of interacting with other developers/companies
3) Use of company-approved technologies or components
4) The requirement to validate the structure of the data using a DTD

Most developers are probably familiar with XML and the tools used to
manipulate it.
Most developers have probably never heard of JSON (non of my co-workers had
when I suggested it recently).

Therefore, saving an extra few kb of data transmission by using JSON might
not be worth it when you consider all the other real-world factors.

> JSON is much better as the
> ECMAScript interpreter can parse that directly to JS objects.

Which may not be the desired functionality, in which case you need to write
code to parse the objects.

Signature

Matt Kruse
http://www.JavascriptToolbox.com

Richard Cornford - 30 May 2005 02:02 GMT
>> That is a bad idea.
>
[quoted text clipped - 5 lines]
> Perhaps if you define sub-optimal by only considering
> the size of the data delivered.

Who is only considering the size of the download? The processing of that
XML on the client into a form that can be employed is a significant
factor. With JSON you are 100% guaranteed to have a native-code
client-side parser available whenever you are going to be in a position
to do something with the data.

> Other factors which may contribute to picking the
> "optimal" solution include:

Is this you usual marketing-speak employment of the term 'solution' or
its normal English meaning? (it is difficult to tell with you)

> 1) Ease of interacting with an existing system
> 2) Ease of interacting with other developers/companies

XML sent to a client has to satisfy same origin policy so the output
format for the client is not limited by data interchange formats. The
only exception that I can think of pre-existing web services using SOAP,
as a reason for preferring XML.

> 3) Use of company-approved technologies or components

Only significant if the person doing the approving doesn't have the
sense to see through the buzzwords and understand why they are choosing
technologies.

> 4) The requirement to validate the structure of the
    data using a DTD

And how often are you going to be doing that on the client? And if you
were you would be better off validating against a Schema as that avoids
having yet another client-side parser to interpret the DTD.

> Most developers are probably familiar with XML and the
> tools used to manipulate it.

Such as writing an XSLT to output JSON from it.

> Most developers have probably never heard of JSON
> (non of my co-workers had when I suggested it recently).

Server-side programmers in other languages have no reason to know about
JSON. That doesn't mean they cannot be persuaded that it is the best
format for sending date to client-side ECMAScript. If they understand
XML they are not going to have much trouble understanding comma
separated name value pairs wrapped in braces.

> Therefore, saving an extra few kb of data transmission
> by using JSON might not be worth it when you consider
> all the other real-world factors.

You are only considering the size of the download. Once downloaded it is
still necessary to process the data into a useable form. The tools for
that with JSON are native to all ECMAScript interpreters, for XML the
browser may or may not provide some (and if it does they will likely
differ between browsers) and if it does not you have to download and
execute an XML parser implemented in client-side code.

>> JSON is much better as the ECMAScript
>> interpreter can parse that directly to JS objects.
>
> Which may not be the desired functionality, in which case
> you need to write code to parse the objects.

What are you talking about? If the objects are not already in the
desired form (and with JSON they can be in exactly the required form,
which is unlikely to ever be true of an XLM DOM) all you have to do is
read the pertinent data from the JS objects. That is no worse than
extracting the data from XML nodes, and potentially much better.

Richard.
VK - 30 May 2005 08:39 GMT
There was an extensive discussion on the event matter here:
<http://groups-beta.google.com/group/comp.lang.javascript/browse_frm/thread/083ed
9630b81dee9/cd81fab7ffdfadd7#cd81fab7ffdfadd7
>

They tried so hard, to convince me that there was NO problem of event
source traking in programmed handlers, so I almost believed it :-)

This works on any nesting deep, even with links inside:

function addClickListener(obj) {
if (obj.addEventListener) {
// To avoid multiple bubbles in FF,
// we're capturing events on the up->down (capturing) phase,
// so the bubbles history doesn't  matter to us.
// Also we're using function wrapper to pass the object
// to the event handler:
 obj.addEventListener('click', function(){myFunction(obj);}, true);
}
else if (obj.attachEvent) {
// We're using function wrapper to pass the object
// to the event handler:
 obj.attachEvent('onclick', function(){myFunction(obj);});
}
else {
// Some under-done wannabe browser, just skip on it ?
}
}

function myFunction(obj) {
// Do what you want with obj, this is the right one - 100% guarantee
:-)
}

If you need to handle the event object as well (say, cancel it), you
need to update it as follow:

obj.addEventListener('click', function(e){myFunction(obj, e);}, true);
obj.attachEvent('onclick', function(){myFunction(obj, null);});

function myFunction(obj, evt) {
// Do what you want with obj, this is the right one - 100% guarantee
:-)
// Do what you want with evt event, just remember that in FF
// this event is captured at the downfall phase:
// 1. You have to use stopPropagation() instead of cancelBubble to
cancel the event
// 2. If you do so, any underlaying elements like links will never
receive the event
}

Faced quod potui, faciant meliora potentes...
VK - 30 May 2005 14:11 GMT
an updated variant taking into account the newly discovered array
referencing bug... sorry... "closure's feature" of both browsers. The
event attacher is moved out of the main loop.

<html>
<title>Test</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">

<script type="text/javascript">
<!--

function init() {
var arr = document.getElementsByTagName('DIV');
for (i=0; i<arr.length; i++) {
 addClickListener(arr[i]);
}
}

function addClickListener(obj) {
if (obj.addEventListener) {
 obj.addEventListener('click', function(e){clickHandler(obj,e);},
true);
}
else if (obj.attachEvent) {
 obj.attachEvent('onclick', function(){clickHandler(obj,null);});
}
else {
// Some under-done browser.
}
}

function test(e) {
alert(this);
}

function clickHandler(obj, evt) {
var e = (evt!=null)? evt : event;
var t = (evt!=null)? e.target : e.srcElement;

// if we need to disable underlaying links / form elements:
(evt!=null)? e.preventDefault() : e.returnValue=false;

alert('Click captured by '+ obj.id.toUpperCase() + '\n\n'+
      'This click originated from ' + t.id.toUpperCase());
}
//-->
</script>
</head>

<body bgcolor="#FFFFFF" onload="init()">
<div id="div1">DIV1 <span id="span1">SPAN1 <a id="a1"
href="bogus1.htm"> A1 </a></span></div>
<div id="div2">DIV2 <span id="span2">SPAN2 <a id="a2"
href="bogus2.htm"> A2 </a></span></div>
<div id="div3">DIV3 <span id="span3">SPAN3 <a id="a3"
href="bogus3.htm"> A3 </a></span></div>
</body>
</html>
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.