By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,873 Members | 1,040 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,873 IT Pros & Developers. It's quick & easy.

Works in ie and opera not mozilla

P: n/a
This code works fine in ie and opera but not at all in Mozilla.
Anybody got a clue as to how to get it right?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<script language="JavaScript" type="text/javascript">
function show(that)
{
if (box.style.visibility=='hidden') { that.style.visibility =
'visible'};
}
</script>
<html>
<head>
<title>Untitled</title>
</head>
<body>
<div style="width: 100px; height: 100px; border: 1px solid Black;
background-color: Aqua;" onclick="show(box)">help</div>
<div id="box" style=" position: relative; width: 100px; height: 100px;
border: 1px solid Black; background-color: Aqua; visibility:
hidden;">me</div>
</body>
</html>

Thanks

Tony Kulik
Jul 20 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Uhm I am surprised it works at all.
You invoke it as onClick="show(box)".
Now we have two issues there: calling in as box, that is not even in between
quotes, the object should have triggered an error anyway: box is not a
global variable somewhere defined - and you agree yopu never defined such a
variable via script.

Yet it works, so the only reason it can work is that that word, box, is
handled as if it were a globally defined variable that you didn't define. NO
way out.
So the scripting engine must be assigning it to the window object: in fact
on IE:
onClick="show(window.box)" works but
onClick="show(document.box)" doesn't.
So the engine did a thing ON YOUR BEHALF.

Now, I hope you realize that this assignment to the window object of the
variable named box is an assignment that the scripting engine is clearly
doing, yet it was _not_ supposed to do it - thence the fact Mozilla refuses
(rather "correctly" _perhaps_ we can say) to parse it: in fact Netscape 7
error says (which proves my point): "box is not defined". That is, NS 7
"agrees" that that call would have implied a globablly defined variable
being put into existance by you via script not via dom.

Now, I suggest to you to change that. The fact on IE it works can be
ascribed only to this: the DOM engine stores in a global environment the
names of the layers as globally defined variables - this is rather
surprising. Maybe some are already familiar with this, but the errors
reported by Netscape 7 too prove that this behaviour is weird, and though
helpful can be labeled as such, as weird to say the least.

The correct way to run that statement and make it work everywhere is this:

onClick="show(document.getElementById('box'))".
note the single apex around box: 'box'

PS please change also:
if (box.style.visibility=='hidden') { that.style.visibility =...
into a more consistent:
if (that.style.visibility=='hidden') { that.style.visibility =...

namley change 'box' into 'that' or the NS7 error would persist,
ciao
Alberto
http://www.unitedscripters.com/

"tony kulik" <tk*******@ackulik.com> ha scritto nel messaggio
news:3f***************@news1.news.adelphia.net...
This code works fine in ie and opera but not at all in Mozilla.
Anybody got a clue as to how to get it right?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<script language="JavaScript" type="text/javascript">
function show(that)
{
if (box.style.visibility=='hidden') { that.style.visibility =
'visible'};
}
</script>
<html>
<head>
<title>Untitled</title>
</head>
<body>
<div style="width: 100px; height: 100px; border: 1px solid Black;
background-color: Aqua;" onclick="show(box)">help</div>
<div id="box" style=" position: relative; width: 100px; height: 100px;
border: 1px solid Black; background-color: Aqua; visibility:
hidden;">me</div>
</body>
</html>

Thanks

Tony Kulik

Jul 20 '05 #2

P: n/a
Lee
tony kulik said:

This code works fine in ie and opera but not at all in Mozilla.
Anybody got a clue as to how to get it right?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<script language="JavaScript" type="text/javascript">
function show(that)
{
if (box.style.visibility=='hidden') { that.style.visibility =
'visible'};
} <div style="width: 100px; height: 100px; border: 1px solid Black;
background-color: Aqua;" onclick="show(box)">help</div>


Allowing you to access the <DIV> with id "box" using that
shortcut is considered dangerous by many people, some of
whom write browser specifications.

function show(that){
if (document.getElementById("box").style.visibility== "hidden"){
document.getElementById(that).style.visibility="vi sible";
}
}

onclick="show('box')"

It's not clear why you have "box" hard-coded in one case, but
pass it in as an argument in the other, or why you check to
see if it is hidden before making it visible.

Jul 20 '05 #3

P: n/a
tony kulik wrote:
This code works fine in ie and opera but not at all in Mozilla.
Anybody got a clue as to how to get it right?
[...]
function show(that)
{
if (box.style.visibility=='hidden') { that.style.visibility =
'visible'};
}
[...]
<div style="width: 100px; height: 100px; border: 1px solid Black;
background-color: Aqua;" onclick="show(box)">help</div>
<div id="box" style=" position: relative; width: 100px; height: 100px;
border: 1px solid Black; background-color: Aqua; visibility:
hidden;">me</div>
[...]


Only IE makes elements with `id' attributes automagically properties of
the global (window) object (with the same identifier.) Reference the `div'
element using the methods appropriate to the DOM of the UA instead.

http://pointedears.de.vu/scripts/dhtml.js can help you in simplifying your
code that way and keep it working in known DHTML capable user agents at the
same time. See http://pointedears.de.vu/scripts/test/whatami pp. for details.

And if you use `box' anyway you don't need the `that' named argument in
your method. Or if you need that argument for the method to serve a general
purpose that `box.style.visibility' should be `that.style.visibility'. BTW:
For Netscape 4.x you should use CSS classes and the `class' attribute
instead of the `style' attribute.
HTH

PointedEars

Jul 20 '05 #4

P: n/a
Thinking the topic over, and noticing you've got confirmations, I can none
the less ease your likely sense of puzzlement in hearing that a procedure
which works on IE should none the less be considered as wrong. Browsers can
have internal engines arranged in a very odd way at times.

I remember on this very samegbroup a debate I think in 2001 about a strange
way that javascript has to handle image names:
onMouseOver="imageName.src='newfoo.gif'"
this reference, if that imageName is the name of an image, works as if the
variable called imageName would have been defined not as an item of the
images collection but even as a globally defined variable... again!

Once Danny Goodman ( http://www.dannyg.com ) said, kindly answering an
email, that though this behaviour may appear 'illogic', yet that is the way
many javascript interpreters work with images.
A full, detailed documentation of this strange behaviour with image names
handled as _window_ objects is reported at:
http://www.unitedscripters.com/spell...mystery.html#4

Keeping fixed what we said in our previous posts, yet you can find there
that there is _also_ a strange tendency to handle objects which should NOT
be direct window dependancies as if they were; that is, strange exceptions
that I cannot truly explain.

I think that when IE behaves assigining to the window object the names of
the layers, it must have been just following that type of marginal approach:
image names as global variables, thus why not layer names...? - I was just
trying to find a reason you see for that strange choice - which as I said I
find it either 'dangerous' or at least illogical - illogical inasmuch as it
is highly inconsistent with all the hierarchical appraoch to javascript as
we hear and as we ourselves keep predicating all the time. Have a look at
that mystery.html if you want and you may find 'solace': it is not the first
time we see scripting engines doing pretty strange things that nearly
disavow the canon they elsewhere uphold :)
ciao
Jul 20 '05 #5

P: n/a
Fox


tony kulik wrote:

This code works fine in ie and opera but not at all in Mozilla.
Anybody got a clue as to how to get it right?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<script language="JavaScript" type="text/javascript">
function show(that)
{
if (box.style.visibility=='hidden') { that.style.visibility =
'visible'};
}
</script>
<html>
<head>
<title>Untitled</title>
</head>
<body>
<div style="width: 100px; height: 100px; border: 1px solid Black;
background-color: Aqua;" onclick="show(box)">help</div>
<div id="box" style=" position: relative; width: 100px; height: 100px;
border: 1px solid Black; background-color: Aqua; visibility:
hidden;">me</div>
</body>
</html>

Thanks

Tony Kulik


You're playing fast and loose with the object model. You cannot assume
that the "current" object (implied "this" which your usage is relying
on) is going to be the object that "box" is a member of... as you can
well see with mozilla. IE has long had a reputation for "do as I want,
not as I say".

Even in IE, this should not work because box is a member of document.all
-- however, you are refering to it in the context of of an unidentified
(no ID attribute) DIV, which should be one level below document.all [as
in: document.all.unidentifiedDIV.onclick() -- for which box is
definitely not a member]. [IE has so many redundancies all through the
object model, it probably has another copy of this reference where it's
accessible in this fashion.]

You need to keep your object relationships straight if you are going to
expect to be able to handle an object oriented language like JavaScript
(but apparently not nearly as strict a requirement in JScript).
Jul 20 '05 #6

P: n/a
Nix

"tony kulik" <tk*******@ackulik.com> wrote in message
news:3f***************@news1.news.adelphia.net...
This code works fine in ie and opera but not at all in Mozilla.
Anybody got a clue as to how to get it right?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<script language="JavaScript" type="text/javascript">
function show(that)
{
if (box.style.visibility=='hidden') { that.style.visibility =
'visible'};
}
</script>
<html>
<head>
<title>Untitled</title>
</head>
<body>
<div style="width: 100px; height: 100px; border: 1px solid Black;
background-color: Aqua;" onclick="show(box)">help</div>
<div id="box" style=" position: relative; width: 100px; height: 100px;
border: 1px solid Black; background-color: Aqua; visibility:
hidden;">me</div>
</body>
</html>

Thanks

Tony Kulik


try some thing like this to swich layers on & off

document.getElementById('myLayer').style.visibilit y="hidden"
or

document.getElementById('myLayer").style.visibilit y="visible"

Nick

http://www.nick.p.lamb.btinternet.co.uk/
Jul 20 '05 #7

P: n/a
Vicomte De Valmont wrote:

I remember on this very samegbroup a debate I think in 2001 about a strange
way that javascript has to handle image names:
onMouseOver="imageName.src='newfoo.gif'"
this reference, if that imageName is the name of an image, works as if the
variable called imageName would have been defined not as an item of the
images collection but even as a globally defined variable... again!
.... A full, detailed documentation of this strange behaviour with image names
handled as _window_ objects is reported at:
http://www.unitedscripters.com/spell...mystery.html#4


Commendable as page effort may be, explanation of how identifiers
used in event handler text are resolved is incorrect. Not to be unkind,
such identifier resolution was always poorly documented in browser
documentation that I know of.

Netscape's Javascript 1.3 documentation describes named image objects as
being reflected as similarly named properties of the document object or,
within a form, of the form object. I havn't tested image reflection on
form objects under NS4, but as it turns out, such reflection need not
have been all that important in practice.

What Netscape failed to document was that
handler text provided for handling events within attribute values of
HTML tags is converted to a function with a special scope chain. This
scope chain comprises function local scope, the element node to which
the event handler is attached, the current form object (if any), the
document object, and finally the global (window) object.

Hence use of an image name as an identifier within event handler code
(supplied within HTML tags) will be resolved by searching the scope
chain of the resultant function (as it should be) where it would be
found as a property of the document - or form if it actually got moved
there.

OTOH, named anchors placed in the document.anchors array were not made
named properties of the document, so an unadorned refererence to an
image name, within event handler text for an A tag, would still resolve
to the image object should IMG and A tags be given the same name in testing.

The "this" value seen within an event handler, or any other javascript
function for that matter, is always supplied in the call to the
function, defaults to the global object if not supplied, and is not
automatically included in scope chains. The point being that whilst
element nodes are included in the scope chain of their handler text
functions, and they are seen as the "this" object within such functions,
scope chain inclusion results from the way browsers process event
handler text rather than following from javascript treatment of the
"this" keyword.

Okay, so far this behavior is classic DOM0 (a.k.a. "early Netscape") and
has been widely implemented in other browsers. There are some caveats on
sources of confusion:

* IE has a tendency to reflect elements given an id or name attribute as
properties of the window object as well, possibly for interoperability
with VBScript but leading to non portable code if used. AIUI, this
behavior has been copied by some but not all other browsers.

* Because scope chain formation for event handler text was poorly
documented, not all current browsers mimic DOM0 event handler scope
chain formation fully. For example, Opera copies IE in making named
elements properties of the window object, but leaves document out of
event handler scope chains. In combination this means the omission of
document from the scope chain may not be all that noticable, but does
allow writing (Opera specific) browser killer code by accident or,
potentially, by design.
My /personal/ style and advice for cross browser scripting is to avoid
short cut identifiers in handler text supplied in HTML, use the "this"
object to refer to the current element in achieving some shortcuts, and
to *not* give global variables or functions the same name as any id or
name value used for HTML elements.
--

HTH,

Dom



Jul 20 '05 #8

P: n/a
"Dom Leonard" <do*************@senet.andthis.com.au> wrote in message
news:OO**************@nnrp1.ozemail.com.au...
<snip>
What Netscape failed to document was that
handler text provided for handling events within attribute
values of HTML tags is converted to a function with a special
scope chain. This scope chain comprises function local scope,
the element node to which the event handler is attached, the
current form object (if any), the document object, and finally
the global (window) object.
When you have described this previously I have though that it didn't
quite correspond with my experience, particularly the suggestion that
the internal implementation was using a - with(obj) - type statements to
selectively set-up a scope chain. On further investigation it seems that
you are correct and my perception of discrepancies arose from a
relatively wide diversity of implementations.

To test the proposition I created the following test page. It creates 10
global properties with the names 'ex0' to 'ex9' then 9 properties on the
document with the names 'ex1' to 'ex9', 8 on the body 'ex2' - 'ex9', 7
on the outer DIV element and so on progressively down the DOM until it
gets to the leaf nodes. Then various onclick handlers attempt to report
the values of the (unqualified) identifiers 'ex0' to 'ex9' to see where
the values are retrieved from (as the first value fond in the scope
chain will be the one reported).

<html>
<head>
<title></title>
<script type="text/javascript">

function setExpandos(){
setExs(window,0, 'global');
setExs(document,1, 'document');
setExOn(document.body,2, 'body');
}
function setExOn(obj, depth, data){
if(obj.nodeType == 1){
setExs(obj,depth, data);
//if(obj.onclick)obj.onclick = showExpandos;
var o = obj.children||obj.childNodes;
for(var c = 0;c < o.length;c++){
setExOn(o[c], (depth+1), (depth+1));
}
}
}
function setExs(obj,start, data){
for(var c = start;c < 10;c++){
obj['ex'+c] = data+((obj.nodeName)?(' '+obj.nodeName):'');
}
}
var res = [
'chain results > ',
'\nex0 = ','', //2
'\nex1 = ','', //4
'\nex2 = ','', //6
'\nex3 = ','', //8
'\nex4 = ','', //10
'\nex5 = ','', //12
'\nex6 = ','', //14
'\nex7 = ','', //16
'\nex8 = ','', //18
'\nex9 = ','' //20
];
function showExpandos(){
var a = res;
a[2] = ex0;
a[4] = ex1;
a[6] = ex2;
a[8] = ex3;
a[10] = ex4;
a[12] = ex5;
a[14] = ex6;
a[16] = ex7;
a[18] = ex8;
a[20] = ex9;
alert(a.join(''));
return false;
}
</script>
</head>
<body onload="setExpandos();">
<div>
<form action="">
<div>
<p>
<input type="button" value="Form Button"
onclick="var a = res;a[2] = ex0;a[4] = ex1;
a[6] = ex2;a[8] = ex3;a[10] = ex4;
a[12] = ex5;a[14] = ex6;a[16] = ex7;
a[18] = ex8;a[20] = ex9;
alert(a.join(''));return false;">
</p>
</div>
</form>
<table>
<thead>
<tr><th><a href="#"
onclick="var a = res;a[2] = ex0;a[4] = ex1;
a[6] = ex2;a[8] = ex3;a[10] = ex4;
a[12] = ex5;a[14] = ex6;a[16] = ex7;
a[18] = ex8;a[20] = ex9;
alert(a.join(''));return false;">
thead</a></th></tr>
</thead>
<tbody>
<tr><td><span>
<a href="#"
onclick="var a = res;a[2] = ex0;a[4] = ex1;
a[6] = ex2;a[8] = ex3;a[10] = ex4;
a[12] = ex5;a[14] = ex6;a[16] = ex7;
a[18] = ex8;a[20] = ex9;
alert(a.join(''));return false;">
tbody</a></span></td></tr>
</tbody>
</table>
</div>
</body>
</html>
Initially testing IE 6, Mozilla 1.3 and Opera 7.11, the three onclick
functions reported (best viewed with a fixed-width font):-

IE 6 Mozilla 1.3 Opera 7.11

button element onclick -------------------------------------

ex0 = global global global
ex1 = document #document document #document global
ex2 = document #document body BODY global
ex3 = document #document 3 DIV global
ex4 = 4 FORM 4 FORM 4 FORM
ex5 = 4 FORM 4 FORM 4 FORM
ex6 = 4 FORM 4 FORM 4 FORM
ex7 = 7 INPUT 7 INPUT 7 INPUT
ex8 = 7 INPUT 7 INPUT 7 INPUT
ex9 = 7 INPUT 7 INPUT 7 INPUT

first link onclick ----------------------------------------

ex0 = global global global
ex1 = document #document document #document global
ex2 = document #document body BODY global
ex3 = document #document 3 DIV global
ex4 = document #document 4 TABLE global
ex5 = document #document 5 THEAD global
ex6 = document #document 6 TR global
ex7 = document #document 7 TH global
ex8 = 8 A 8 A 8 A
ex9 = 8 A 8 A 8 A

second link onclick ---------------------------------------

ex0 = global global global
ex1 = document #document document #document global
ex2 = document #document body BODY global
ex3 = document #document 3 DIV global
ex4 = document #document 4 TABLE global
ex5 = document #document 5 TBODY global
ex6 = document #document 6 TR global
ex7 = document #document 7 TD global
ex8 = document #document 8 SPAN global
ex9 = 9 A 9 A 9 A

Each browser clearly is building a very specific scope chain for these
internally generated event-handling functions.

Mozilla's behaviour is interesting as for the A elements its scope chain
includes all of the element ancestors in the DOM up to the global
object, yet with the form element it has included the body and the outer
DIV but the P and DIV elements that lie between the form and the input
element have been omitted.

<snip>My /personal/ style and advice for cross browser scripting
is to avoid short cut identifiers in handler text supplied
in HTML, use the "this" object to refer to the current element
in achieving some shortcuts, and to *not* give global variables
or functions the same name as any id or name value used for
HTML elements.


I would have to agree with that 100%, especially given that even the
major browsers do not create a consistent scope chain for these
attribute-defined event handling functions.

Richard.
Jul 20 '05 #9

P: n/a
Thank you Dom, I'll save this email and study it a bit.
Actually the page doesn't mean to investigate how/why those unsual behaviour
occur and settle down with a defintive answer (yet we have to concur that a
command like alert( imageName.href ) issued from an anchor which has the
same name of an image should deliver the href of the anchor: in IE6 it
delivers... the SRC of the image - yeah crazy). So the point wiht the page
is not to assess once and for all what is done on the background that can
justify these behaviours: of course something MUST be done, because these
unsual behaviour is there. The point is that whatever it is, it seems to
exit from the traditional hierarchy: that is, the conclusion is: Object
oriented, yet not fully or not always hierarchically oriented!

ciao Thank you for your answer
Alberto

"Dom Leonard" <do*************@senet.andthis.com.au> ha scritto nel
messaggio news:OO**************@nnrp1.ozemail.com.au...
Vicomte De Valmont wrote:

I remember on this very samegbroup a debate I think in 2001 about a strange way that javascript has to handle image names:
onMouseOver="imageName.src='newfoo.gif'"
this reference, if that imageName is the name of an image, works as if the variable called imageName would have been defined not as an item of the
images collection but even as a globally defined variable... again!
...
A full, detailed documentation of this strange behaviour with image names handled as _window_ objects is reported at:
http://www.unitedscripters.com/spell...mystery.html#4


Commendable as page effort may be, explanation of how identifiers
used in event handler text are resolved is incorrect. Not to be unkind,
such identifier resolution was always poorly documented in browser
documentation that I know of.

Netscape's Javascript 1.3 documentation describes named image objects as
being reflected as similarly named properties of the document object or,
within a form, of the form object. I havn't tested image reflection on
form objects under NS4, but as it turns out, such reflection need not
have been all that important in practice.

What Netscape failed to document was that
handler text provided for handling events within attribute values of
HTML tags is converted to a function with a special scope chain. This
scope chain comprises function local scope, the element node to which
the event handler is attached, the current form object (if any), the
document object, and finally the global (window) object.

Hence use of an image name as an identifier within event handler code
(supplied within HTML tags) will be resolved by searching the scope
chain of the resultant function (as it should be) where it would be
found as a property of the document - or form if it actually got moved
there.

OTOH, named anchors placed in the document.anchors array were not made
named properties of the document, so an unadorned refererence to an
image name, within event handler text for an A tag, would still resolve
to the image object should IMG and A tags be given the same name in

testing.
The "this" value seen within an event handler, or any other javascript
function for that matter, is always supplied in the call to the
function, defaults to the global object if not supplied, and is not
automatically included in scope chains. The point being that whilst
element nodes are included in the scope chain of their handler text
functions, and they are seen as the "this" object within such functions,
scope chain inclusion results from the way browsers process event
handler text rather than following from javascript treatment of the
"this" keyword.

Okay, so far this behavior is classic DOM0 (a.k.a. "early Netscape") and
has been widely implemented in other browsers. There are some caveats on
sources of confusion:

* IE has a tendency to reflect elements given an id or name attribute as
properties of the window object as well, possibly for interoperability
with VBScript but leading to non portable code if used. AIUI, this
behavior has been copied by some but not all other browsers.

* Because scope chain formation for event handler text was poorly
documented, not all current browsers mimic DOM0 event handler scope
chain formation fully. For example, Opera copies IE in making named
elements properties of the window object, but leaves document out of
event handler scope chains. In combination this means the omission of
document from the scope chain may not be all that noticable, but does
allow writing (Opera specific) browser killer code by accident or,
potentially, by design.
My /personal/ style and advice for cross browser scripting is to avoid
short cut identifiers in handler text supplied in HTML, use the "this"
object to refer to the current element in achieving some shortcuts, and
to *not* give global variables or functions the same name as any id or
name value used for HTML elements.
--

HTH,

Dom


Jul 20 '05 #10

P: n/a
Richard Cornford wrote:
Dom Leonard wrote:
<snip>
What Netscape failed to document was that
handler text provided for handling events within attribute
values of HTML tags is converted to a function with a special
scope chain. This scope chain comprises function local scope,
the element node to which the event handler is attached, the
current form object (if any), the document object, and finally
the global (window) object.

<snip>
To test the proposition I created the following test page. It creates 10
global properties with the names 'ex0' to 'ex9' then 9 properties on the
document with the names 'ex1' to 'ex9', 8 on the body 'ex2' - 'ex9', 7
on the outer DIV element and so on progressively down the DOM until it
gets to the leaf nodes. Then various onclick handlers attempt to report
the values of the (unqualified) identifiers 'ex0' to 'ex9' to see where
the values are retrieved from (as the first value fond in the scope
chain will be the one reported).
What a useful test page, far more thorough than my previous
investigations on this subject - thank you. Using the framework
provided, I thought to confirm predictions which I would expect to be
true from the scope chain model above. Results were, to say the least,
surprising.

I repost the test page, with experimental code added. Changes to the
showExpandos function are not intended as significant and were only made
to insert trace information and reduce posting size.

<html>
<head>
<title></title>
<script type="text/javascript">

function setExpandos(){
setExs(window,0, 'global');
setExs(document,1, 'document');
setExOn(document.body,2, 'body');
}
function setExOn(obj, depth, data){
if(obj.nodeType == 1){
setExs(obj,depth, data);
//if(obj.onclick)obj.onclick = showExpandos;
var o = obj.children||obj.childNodes;
for(var c = 0;c < o.length;c++){
setExOn(o[c], (depth+1), (depth+1));
}
}
}
function setExs(obj,start, data){
for(var c = start;c < 10;c++){
obj['ex'+c] = data+((obj.nodeName)?(' '+obj.nodeName):'');
}
}

function showExpandos(msg, vargs)
{
msg += "\nchain results >";
for( var i = 1; i < arguments.length; ++i)
{ msg += "\n ex" + (i-1) + " = "
+ arguments[i];
}
alert(msg);
return false;
}
function callOut()
{
return showExpandos('in callOut()',
ex0,ex1,ex2,ex3,ex4,ex5,ex6,ex7,ex8,ex9);
}

var elIds = [ "formButton", "theadLink",
"tbodyLink", "callOutLink"];
var elObjs = [];

function initRotate()
{
var o,id;
for(var i = 0; i < elIds.length; ++i)
{ id = elIds[i];
elObjs[i]=document.getElementById( id);
}
}

function doRotate()
{
var temp = elObjs[0].onclick;
for( var i = 0; i < (elObjs.length-1); ++i)
{ elObjs[i].onclick = elObjs[i+1].onclick;
}
var last = elObjs[elObjs.length-1];
last.onclick = temp;
}

function createTextFunction(bodyText)
{
var d = document.createElement("DIV");
d.innerHTML = '<A href="#" onclick="'
+ bodyText
+ '">dummy</A>';
return d.firstChild.onclick;
}

function testTextFunction()
{
var fbody = "return showExpandos('text function on '"
+ " + this.id,ex0,ex1,ex2,ex3,ex4,ex5,ex6,ex7,ex8,ex9);" ;
var f = createTextFunction( fbody);
var o = {id: "javascript object", onclick: f};
o.onclick();
elObjs[0].onclick = f;
}

function testFuncFunction()
{
var fbody = "return showExpandos('Function function on '"
+ " + this.id,ex0,ex1,ex2,ex3,ex4,ex5,ex6,ex7,ex8,ex9);" ;
elObjs[0].onclick = new Function( fbody);
}

function exciseTest()
{
var btn = elObjs[0];
var btnParent = btn.parentNode;
btnParent.removeChild(btn);
btn.id = "removedButton";
alert("(removed button).form = "
+ (btn.form||"[no value]"));
btn.onclick();
btn.id = "bodyAppendedButton";
document.body.appendChild(btn);
btn.onclick();
btn.parentNode.removeChild(btn);
btn.id = elIds[0];
btnParent.appendChild(btn);
// try setting the same handler on two elements
elObjs[1].onclick = btn.onclick;
alert("Button and thead onclick functions are the same: "
+ (elObjs[0].onclick == elObjs[1].onclick));
}

</script>
</head>
<body onload="setExpandos();initRotate();">
<div>
<form action="">
<div>
<p>
<input type="button" value="Form Button"
id="formButton" onclick="return showExpandos(
'form button text on ' + this.id,
ex0,ex1,ex2,ex3,ex4,ex5,ex6,ex7,ex8,ex9);">
</p>
</div>
</form>
<table>
<thead>
<tr><th><a href="#" id="theadLink";
onclick="return showExpandos('thead text on '+this.id,
ex0,ex1,ex2,ex3,ex4,ex5,ex6,ex7,ex8,ex9);">
thead</a></th></tr>
</thead>
<tbody>
<tr><td><span>
<a href="#" id="tbodyLink";
onclick="return showExpandos('tbody text on '+this.id,
ex0,ex1,ex2,ex3,ex4,ex5,ex6,ex7,ex8,ex9);">
tbody</a></span></td></tr>
</tbody>
</table>
</div>
<div>
<a href="#" onclick="return callOut();"
id="callOutLink"> call out to javascript </a>
</div>
<h3>Experiments</h3>
<a href="#" onclick="doRotate();return false">
1. rotate event handlers
</a>
<p>
<a href="#" onclick="testTextFunction();return false;">
2. replace button onclick with text function
</a>
</p>
<p>
<a href="#" onclick="testFuncFunction();return false;">
3. replace button onclick with Function function
</a>
</p>
<p>
<a href="#" onclick="exciseTest();return false;">
4. excise button from document and call onclick
</a>
</p>
</body>
</html>

=========
The top four button/links, tested in IE6, Mozilla 1.4 and Opera 7.20,
confirm your previous results for the same family of browsers. The "call
out to javascript" link merely confirms the expected and negative result
that functions defined within SCRIPT elements do not somehow inherit a
specialised scope chain when being called.

<EXPERIMENT>

1) If functions created from attribute-defined event handler text in
HTML use the scope chain to resolve identifier short cuts, I would
expect reporting of ex' identifier values to depend on the onclick
function object, and remain invariant if onclick handlers are moved to
different element nodes. The "rotate handlers" link rotates onclick
functions around the top four button and link elements.

For Mozilla and Opera, reporting of values found in the scope chain
follows the event handler function object. For IE, it depends on which
element the handler function is attached to. This latter result was
unexpected.

2) What would be the result of setting an element's (onclick) event
handler to a function created in attribute text when setting the
innerHTML property of an element node which does not even reside in the
document. I would expect Mozilla and Opera results to be "not very
useful" and want to know about IE.

All browsers tested report the scope chain of the handler text function
to be the global object if attached to a simple javascript object. After
this alert, click the form button to see the result on a document
element node.

Mozilla and Opera continue to report a scope chain comprising the global
object. So no special scope chain achieved. IE reports the scope chain
expected from the position of the element node on which the handler is
set. So, why?

3) If I just set a Function object (which should use the global object
as its scope chain under ECMAScript standards) as the event handler,
will IE do anything special.

Test results say no. The new Function() handler only finds and reports
global properties.

4) For the fourth experiment at least, reload the document to get back
to initial conditions. Click the "excise button..." link to initiate,
and following alerts, click the form button and thead links. Discussion
focuses on IE behavior.

4a) What if I remove the button element from the document and call its
onclick handler. IE says it no longer knows about the form in which it
used to reside, but still reports the scope chain as if it were inside
the form.

4b) What if I append the (removed) button element to the document,
outside the form element, and call its onclick handler. At this stage IE
reports a scope chain consistent with the buttons placement in the document.

4c) If the button is put back inside the form, but the thead link's
onclick handler is set to the button's onclick handler, what happens?

IE reports the onclick functions of the button and thead link as the
same function, but the alerts show a different scope chain. As you will
appreciate, this behavior corresponds to that of joined functions as
covered in ECMAScript reference.

[and quickly checking <cite ECMA-262>
This ECMA Standard is based on several originating technologies, the
most well known being JavaScript (Netscape) and JScript (Microsoft).
</cite> Oh my, guess who contributed joined functions !!! ]

</EXPERIMENT>

Initially testing IE 6, Mozilla 1.3 and Opera 7.11, the three onclick
functions reported (best viewed with a fixed-width font):-

IE 6 Mozilla 1.3 Opera 7.11

button element onclick -------------------------------------

ex0 = global global global
ex1 = document #document document #document global
ex2 = document #document body BODY global
ex3 = document #document 3 DIV global
ex4 = 4 FORM 4 FORM 4 FORM
ex5 = 4 FORM 4 FORM 4 FORM
ex6 = 4 FORM 4 FORM 4 FORM
ex7 = 7 INPUT 7 INPUT 7 INPUT
ex8 = 7 INPUT 7 INPUT 7 INPUT
ex9 = 7 INPUT 7 INPUT 7 INPUT

first link onclick ----------------------------------------

ex0 = global global global
ex1 = document #document document #document global
ex2 = document #document body BODY global
ex3 = document #document 3 DIV global
ex4 = document #document 4 TABLE global
ex5 = document #document 5 THEAD global
ex6 = document #document 6 TR global
ex7 = document #document 7 TH global
ex8 = 8 A 8 A 8 A
ex9 = 8 A 8 A 8 A

second link onclick ---------------------------------------

ex0 = global global global
ex1 = document #document document #document global
ex2 = document #document body BODY global
ex3 = document #document 3 DIV global
ex4 = document #document 4 TABLE global
ex5 = document #document 5 TBODY global
ex6 = document #document 6 TR global
ex7 = document #document 7 TD global
ex8 = document #document 8 SPAN global
ex9 = 9 A 9 A 9 A

Each browser clearly is building a very specific scope chain for these
internally generated event-handling functions.
I concur, and reproduced the same results. Obviously, each browser is
attempting to allow identifier short cuts similar to the provisions of
NS4, with implementation dependent mechanisms. No personal surprise here
given DOM0 is not standardised anyway.
Mozilla's behaviour is interesting as for the A elements its scope chain
includes all of the element ancestors in the DOM up to the global
object, yet with the form element it has included the body and the outer
DIV but the P and DIV elements that lie between the form and the input
element have been omitted.
Most interesting. The behaviour looks like code may retain some
resemblance to NS4 code (where scriptable elements created LAYER objects
containing document objects and so on) which has been tweaked in some
places and not others, but this remains conjecture on my part.

In one of your posts several months ago I did notice a description of
searching up the DOM towards the root element to resolve identifiers in
handler text functions, but found it didn't correspond to my own
experience. The mozilla result above certainly explains where such an
account could come from, and can readily see that if I had picked a
different element in the DOM tree for isolated testing at the time, I
could have obtained an unexpected result in need of more thought.
<snip>
... even the
major browsers do not create a consistent scope chain for these
attribute-defined event handling functions.


Agreed well and truly. The picture I am now seeing of indentifier
resolution within attribute-defined event handlers is that all three
browsers tested are using scope chains more or less as proposed at top
of post after allowing for implementation differences of non standard
DOM0 behavior.

Mozilla and Opera are setting the scope chain of (HTML defined) event
handlers in one-time, static fashion.

IE appears to be able to internally distinguish between function objects
that began life as atttribute text within HTML, and function objects
originating in javascript. This does not suprise me, since behaviour
under discussion emulates that of NS4, and NS4 recorded the provenance
of functions overtly, listing Function as the constructor of global
javascript functions, EventHandler as the constructor of
attibute-defined functions and Closure for nested functions or those
defined within a "with (obj)" construct at file level.

IE appears to have engineered in support for dynamic scripting as well.
The simplest explanation that I can hope to offer is that the scope
chain recorded in the [[Scope]] property of event handler functions
derived from HTML attribute values is calculated when the handler is
defined, when set on an element node as an event handler, or should
element nodes possessing such handlers be inserted into the document.
Either in every case or as required, joined functions are used to cover
the case of setting the same attribute-defined function on multiple
elements.
Again, my thanks for the reply and test page.

Dom



Jul 20 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.