DOM dynamically built table and addEventListener....

Q

Quarco

This one is driving me nuts....



var tbl = document.createElement("table");
var tbody = document.createElement("tbody");

for(var i=0; i<10; i++) {
var row = document.createElement("tr");
var curVAR = someCurrentValueOfArray;

row.addEventListener('click', function(e) {
alert(curVAR);
}, false);

var cell = document.createElement("td");
var cellText = document.createTextNode(i);
cell.appendChild(cellText); row.appendChild(cell);

tbody.appendChild(row);
}
tbl.appendChild(tbody);
document.getElementById('tdiv').appendChild(tbl);

====

Now... Why isn't the curVAR 'assigned' to the row-alert-function???.
if I click one of the rows, only the last curVAR (10) is alerted, but the
i-variable is nicely showed 0 to 9 in the row....

Anyone???

Thanx in advance...
 
J

Joost Diepenmaat

Quarco said:
This one is driving me nuts....



var tbl = document.createElement("table");
var tbody = document.createElement("tbody");

for(var i=0; i<10; i++) {
var row = document.createElement("tr");
var curVAR = someCurrentValueOfArray;

row.addEventListener('click', function(e) {
alert(curVAR);
}, false);

var cell = document.createElement("td");
var cellText = document.createTextNode(i);
cell.appendChild(cellText); row.appendChild(cell);

tbody.appendChild(row);
}
tbl.appendChild(tbody);
document.getElementById('tdiv').appendChild(tbl);

====

Now... Why isn't the curVAR 'assigned' to the row-alert-function???.
if I click one of the rows, only the last curVAR (10) is alerted, but the
i-variable is nicely showed 0 to 9 in the row....

Anyone???


The i and curVar variables are re-assigned in the loop (javascript
does not have block scope, only function scope), so all your event
handlers are closing over the same curVar variable, which will have
someCurrentEtc[9] as its value at the end of the loop.

You need to create a new variable to close over, by creating a new
scope:

(function(curVar) { // or make a named function and call that
row.addEventListener('click', function(e) {
alert(curVAR);
}, false);
})(curVar);
 
J

Jorge

Quarco said:
Now... Why isn't the curVAR 'assigned' to the row-alert-function???.
if I click one of the rows, only the last curVAR (10) is alerted, but the
i-variable is nicely showed 0 to 9 in the row....

You could save curVar as a property of the element ( td / tr ) :

<html><head><script>
window.onload= function () {
var d= document,
anArray= ['a0','b1','c2','d3','e4','f5','g6','h7','i8','j9'],
y= function (p) { return d.createElement(p) },
tbody= y("tbody"),
i, cell;

for(i= 0; i< 10; i++) {
(tbody.appendChild(y('tr'))).appendChild(cell= y("td"));
cell.innerHTML= i;
cell.curVAR= anArray;
cell.addEventListener('click', function(e) { alert(this.curVAR) },
false);
}

(d.getElementById('tdiv').appendChild(y("table"))).appendChild(tbody);
};
</script></head><body><div id="tdiv"></div></body></html>

--Jorge.
 
T

Thomas 'PointedEars' Lahn

Jorge said:
You could save curVar as a property of the element ( td / tr ) :

Recommended against because that would mean augmenting a host object which
is error-prone. Search the archives.


PointedEars
 
Q

Quarco

Taking a bow...
Thank you Joost...!!!


:)


Joost Diepenmaat said:
Quarco said:
This one is driving me nuts....



var tbl = document.createElement("table");
var tbody = document.createElement("tbody");

for(var i=0; i<10; i++) {
var row = document.createElement("tr");
var curVAR = someCurrentValueOfArray;

row.addEventListener('click', function(e) {
alert(curVAR);
}, false);

var cell = document.createElement("td");
var cellText = document.createTextNode(i);
cell.appendChild(cellText); row.appendChild(cell);

tbody.appendChild(row);
}
tbl.appendChild(tbody);
document.getElementById('tdiv').appendChild(tbl);

====

Now... Why isn't the curVAR 'assigned' to the row-alert-function???.
if I click one of the rows, only the last curVAR (10) is alerted, but the
i-variable is nicely showed 0 to 9 in the row....

Anyone???


The i and curVar variables are re-assigned in the loop (javascript
does not have block scope, only function scope), so all your event
handlers are closing over the same curVar variable, which will have
someCurrentEtc[9] as its value at the end of the loop.

You need to create a new variable to close over, by creating a new
scope:

(function(curVar) { // or make a named function and call that
row.addEventListener('click', function(e) {
alert(curVAR);
}, false);
})(curVar);
 
J

Jorge

Recommended against because that would mean augmenting a host object which
is error-prone.  Search the archives.

I didn't know, and I do it all the time !
Would you please tell me why, in a few words ?
Is it a problem, specifically, of a certain browser ?
(I'll look into the archives as well, I promise)

Thanks,
--Jorge.
 
J

Jorge

Recommended against because that would mean augmenting a host object which
is error-prone.  Search the archives.

I didn't know, and I do it all the time !
Would you tell me why is it bad, in a few words ?
(I'll look into the archive as well, I promise)

Thanks,
--Jorge.
 
T

Thomas 'PointedEars' Lahn

Jorge said:
I didn't know, and I do it all the time !

Tough luck.
Would you please tell me why, in a few words ?

In contrast to native objects, host objects do not need to support
augmentation. See the ECMAScript Language Specification, Edition 3 Final,
subsection "8.6.2 Internal Properties and Methods".
Is it a problem,
Yes.

specifically, of a certain browser ?

No, it can cause your Web application to break. Silently, or with an error
message. Anywhere, anytime.
(I'll look into the archives as well, I promise)

Good.


HTH

PointedEars
 
J

Jorge

Tough luck.


In contrast to native objects, host objects do not need to support
augmentation.  See the ECMAScript Language Specification, Edition 3 Final,
subsection "8.6.2 Internal Properties and Methods".


No, it can cause your Web application to break.  Silently, or with an error
message.  Anywhere, anytime.

But, for example :

var y= function (p) { return document.createElement(p) },
e= y('tag');

e.property= "whatever";

Is e a "host object" ?

Or you mean :

(y('tag')).property= "whatever";

??

--Jorge.
 
T

Thomas 'PointedEars' Lahn

Jorge said:
Thomas said:
[Trying to augment host objects] can cause your Web application to
break. Silently, or with an error message. Anywhere, anytime.

But, for example :

var y= function (p) { return document.createElement(p) },

This as it is does not make much sense. See our recent discussion about the
viability of Prototype.js's $() method.
e= y('tag');

e.property= "whatever";

Is e a "host object" ?

`e' is *a reference to* a host object then (probably an object that
implements an element-related interface of W3C DOM Level 2 HTML).

In ECMAScript implementations, you can only work with references to objects,
never with objects directly.
Or you mean :

(y('tag')).property= "whatever";

??

You could also write

y('tag').property = "whatever";

or

[{foo: y('tag')}][0]["foo"].property = "whatever";

and so on with the same (here: possibly disastrous) outcome. How you
construct the reference to an object makes no difference regarding the
kind of object you are referring to.

However, your second variant adds further error-proneness as y() may not
return an object reference or a primitive value convertible to an object in
which case the property lookup would then result in a TypeError (exception).

With the first variant you can at least do feature-testing on the return
value and perhaps also on the property before you attempt to assign to the
property of the object; that would generally seem to be a wise course of
action, with the exception of universally supported properties of native
objects.


Please trim your quotes.


PointedEars
 
J

Jorge

In contrast to native objects, host objects do not need to support
augmentation. See the ECMAScript Language Specification, Edition 3 Final,
subsection "8.6.2 Internal Properties and Methods".

"Every object (including host objects) must implement the
[[Prototype]]
and [[Class]] properties and the [[Get]], [[Put]], [[CanPut]],
[[HasProperty]], [[Delete]], and [[DefaultValue]] methods."

"Host objects may implement these methods in any manner unless
specified
otherwise; for example, one possibility is that [[Get]] and [[Put]]
for
a particular host object indeed fetch and store property values but
[[HasProperty]] always generates false."

Well, this is what I understand :

1- Host objects must implement the Get and Put (and others) methods.
2- The way they implement these methods is not specified ("any
manner").

I hope that "implement in any manner" doesn't mean that a get method
might not fetch a property's value, nor that a put method might
not store it...

It's just that the manner in which they *do it* might be "any
manner".

And as long as a property can be read/written, does it matter in what
"manner" it's done ?

Or the problem is with any of the other methods, not with get/put ?
[Trying to augment host objects] can cause your Web application to
break.  Silently, or with an error message.  Anywhere, anytime.

Is it a certain browser that has these problems ?
(I really don't care about JS/ES outside of a browser).
How you
construct the reference to an object makes no difference regarding the
kind of object you are referring to.

You're right, I thought about it and got it (just after hitting
google's
'post' button, and before reading your post). Thanks for having the
patience to answer so well and politely.
Please trim your quotes.
(trimmed)

Thanks,
--Jorge.
 
T

Thomas 'PointedEars' Lahn

Jorge said:
Thomas said:
In contrast to native objects, host objects do not need to support
augmentation. See the ECMAScript Language Specification, Edition 3
Final, subsection "8.6.2 Internal Properties and Methods".

"Every object (including host objects) must implement the [[Prototype]]
and [[Class]] properties and the [[Get]], [[Put]], [[CanPut]],
[[HasProperty]], [[Delete]], and [[DefaultValue]] methods."

"Host objects may implement these methods in any manner unless specified
otherwise; for example, one possibility is that [[Get]] and [[Put]] for a
particular host object indeed fetch and store property values but
[[HasProperty]] always generates false."

Well, this is what I understand :

1- Host objects must implement the Get and Put (and others) methods.
2- The way they implement these methods is not specified ("any manner").

I hope that "implement in any manner" doesn't mean that a get method
might not fetch a property's value, nor that a put method might not store
it...

But that is exactly what it means.
It's just that the manner in which they *do it* might be "any manner".
No.

And as long as a property can be read/written, does it matter in what
"manner" it's done ?

No, the "manner" may also include throwing a runtime exception. See below.
Or the problem is with any of the other methods, not with get/put ?

[[Get]] and [[Put]] are of primary concern as they are used in quite a
number of ECMAScript algorithms, particularly in those for property
accessors and assignments.
[Trying to augment host objects] can cause your Web application to
break. Silently, or with an error message. Anywhere, anytime.

Is it a certain browser that has these problems ?

This is obviously impossible to say until you have tested all properties in
all known past and current browsers with all possible values. And it does
not mean anything for future versions or browsers you do not know of yet.

It is known of the MSHTML DOM that a host object in the scope chain prevents
the modification of its properties ([[Put]]) that are references to host
objects themselves (element objects for named or ID'd elements), and that
certain properties cause a runtime error on read access ([[Get]]). This is
proof that implementations do follow the specification in that regard.

Or consider the object referred to by the `style' property of element
objects in HTML DOMs. It has certain standardized and proprietary shortcut
properties for assigning CSS property values. If you assign a value to such
a property ([[Put]]) and that value is not valid for that property, you will
observe that the property does not have the assigned value but the original
value in several implementations.

Since such proof exists, it would appear to be unwise to run the risk of
breaking your script with trying to augment host objects.
(I really don't care about JS/ES outside of a browser).

However, Web browsers are only a subset of scriptable user agents.
You're right, I thought about it and got it (just after hitting google's
'post' button, and before reading your post). Thanks for having the
patience to answer so well and politely.

You are welcome.


PointedEars
 
J

Jorge

I hope that "implement in any manner" doesn't mean that a get method
But that is exactly what it means.
BTW, I found this article that you were interested in:
<There's at least one other: <news:[email protected]>

Still, I can't figure out why, if this is so crude, I have never had a
problem with it.
Might it be because I never program for nor test in IEs ?
If the property can be set and can be read, why isn't it safe to go on
with it ?

Is there any doc online, in the browser's libraries, or anywhere, that
says clearly "don't do this", and why not ?
(in w3c, Mozilla, MS, Opera, Webkit...)

TIA,
--Jorge.
 
T

Thomas 'PointedEars' Lahn

Jorge said:
Still, I can't figure out why, if this is so crude, I have never had a
problem with it.

You got away jumping a red light 999 times now.
Might it be because I never program for nor test in IEs ?
No.

If the property can be set and can be read,

If. I have showed that there are cases where this is not possible.
why isn't it safe to go on with it ?

You cannot know which execution environment your code is exposed to during
its life cycle.
Is there any doc online, in the browser's libraries, or anywhere, that
says clearly "don't do this", and why not ?

I have pointed you to the language specification already.
(in w3c, Mozilla, MS, Opera, Webkit...)

This is a feature that can be expected with conforming language
implementations. I wonder what is so difficult to understand about that.


PointedEars
 
V

VK

Still, I can't figure out why, if this is so crude, I have never had a
problem with it.
Might it be because I never program for nor test in IEs ?
If the property can be set and can be read, why isn't it safe to go on
with it ?

I would disregard whatever Thomas is saying unless it is a request for
a particular standard reference where he is pretty good. By having no
practical programming experience, he has made a credo of the type "it
doesn't fail in any place anyone knows about, but it may fail in some
place no one knows about". This gives him an opportunity for the
endless and useless pedantic rambling which is IMHO the only reason
he's posting here. For a recent sample he does believe or pretending
to believe that any script using window.onload is error prone and the
only safe alternative is using <body onload=... Sapienti sat.

For the possibility of DOM object augmentation failure you may account
expando flag state for IE. See
http://msdn.microsoft.com/en-us/library/ms533747.aspx

I never in my life saw yet this flag being used by anyone nor I even
know if it still does work, but if we decided to explore the most low
probable yet at least possible situations then here my two bucks.
 
T

Thomas 'PointedEars' Lahn

VK said:
Still, I can't figure out why, if this is so crude, I have never had a
problem with it.
Might it be because I never program for nor test in IEs ?
If the property can be set and can be read, why isn't it safe to go on
with it ?

I would disregard whatever Thomas is saying unless it is a request for
a particular standard reference where he is pretty good. By having no ^^
practical programming experience, [...]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ROTFL. Weren't you supposed to be somewhere else?


PointedEars
 
J

Jorge

For the possibility of DOM object augmentation failure you may account
expando flag state for IE. Seehttp://msdn.microsoft.com/en-us/library/ms533747.aspx

Yep. The more I google around for this, the more convinced I am that
this "law" has to do with (yet another) buggy IE behaviour.

For example :
"* Even though it is legal to retrieve DOM objects and subsequently
storing
custom properties and attributes in them, you should not do it for
several
reasons."
(..)
"4. I won't name any names in particular, but a certain browser made
by
Microsoft does not tolerate custom properties and attributes on DOM
objects very well, particularly when the objects are added to the
DOM
dynamically and exceptions are thrown. The more elements that are
generated, the more custom properties, and the more exceptions that
are
thrown, the worse it gets."

OTOH, Safari/Webkit's automated tests check specifically that DOM
objects' *custom properties* are correctly preserved after garbage
collection :
(and that's a +2 years-old test log !)

<http://paste.lisp.org/display/20395>

+This page tests whether custom properties on DOM objects persist
after garbage collection.
+
+If the test passes, you'll see a series of 'PASS' messages below.
+
+DOM OBJECTS BEFORE GARBAGE COLLECTION:
+PASS: document.implementation.myCustomProperty should be 1 and is.
+PASS: document.myCustomProperty should be 1 and is.
+PASS: document.body.myCustomProperty should be 1 and is.
...etc.

Note, however this paragraph in the test log :

+Because neither WinIE nor FF has reasonable or predictable behavior
in this scenario, this test just documents our behavior to ensure that
we don't change it accidentally. It is not a prescription for how
things should behave.

And that, Thomas, explains why these bugs have never bitten me... :

because in Safari/WebKit, those things **work fine, as they should**.

--Jorge.
 
J

Jorge

I would disregard whatever Thomas is saying unless it is a request for
a particular standard reference where he is pretty good. By having no

                                                                     ^^> practical programming experience, [...]

  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ROTFL.  Weren't you supposed to be somewhere else?

PointedEars

Please trim your quotes...

/8¬)

--Jorge.
 
V

VK

Yep. The more I google around for this, the more convinced I am that
this "law" has to do with (yet another) buggy IE behaviour.

I'm missing the reason to call it a "bug". It is an additional flag in
Microsoft model allowing to lock/unlock "document" object
augmentation.
a certain browser made by
Microsoft does not tolerate custom properties and attributes on DOM
objects very well, particularly when the objects are added to the
DOM
dynamically and exceptions are thrown. The more elements that are
generated, the more custom properties, and the more exceptions that
are
thrown, the worse it gets."

I guess you are quoting some resource, but which one? "Microsoft does
not tolerate custom properties" is a big news for me in account of the
technology of behaviors specially made to have as many different
custom properties as one wants - besides the regular object
augmentation. Possibly the quoted source contains some explained test
cases to sustain such claim, but again: what is this source?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top