Works in ie and opera not mozilla

Discussion in 'Javascript' started by tony kulik, Oct 25, 2003.

  1. tony kulik

    tony kulik Guest

    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
     
    tony kulik, Oct 25, 2003
    #1
    1. Advertising

  2. 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" <> ha scritto nel messaggio
    news:...
    > 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
    >
    >
     
    Vicomte De Valmont, Oct 25, 2003
    #2
    1. Advertising

  3. tony kulik

    Lee Guest

    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="visible";
    }
    }

    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.
     
    Lee, Oct 25, 2003
    #3
  4. 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
     
    Thomas 'PointedEars' Lahn, Oct 25, 2003
    #4
  5. 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/spellbinder/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
     
    Vicomte De Valmont, Oct 25, 2003
    #5
  6. tony kulik

    Fox Guest

    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).
     
    Fox, Oct 26, 2003
    #6
  7. tony kulik

    Nix Guest

    "tony kulik" <> wrote in message
    news:...
    > 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.visibility="hidden"
    or

    document.getElementById('myLayer").style.visibility="visible"

    Nick

    http://www.nick.p.lamb.btinternet.co.uk/
     
    Nix, Oct 26, 2003
    #7
  8. tony kulik

    Dom Leonard Guest

    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/spellbinder/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
     
    Dom Leonard, Oct 26, 2003
    #8
  9. "Dom Leonard" <> wrote in message
    news:OO%mb.25$...
    <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.
     
    Richard Cornford, Oct 27, 2003
    #9
  10. 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" <> ha scritto nel
    messaggio news:OO%mb.25$...
    > 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/spellbinder/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
    >
    >
    >
    >
    >
    >
    >
     
    Vicomte De Valmont, Oct 28, 2003
    #10
  11. tony kulik

    Dom Leonard Guest

    Re: Works in ie and opera not mozilla [ event handlers and joinedfunctions ]

    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;
    }
    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;
    elObjs=document.getElementById( id);
    }
    }

    function doRotate()
    {
    var temp = elObjs[0].onclick;
    for( var i = 0; i < (elObjs.length-1); ++i)
    { elObjs.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
     
    Dom Leonard, Oct 29, 2003
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. zorhel
    Replies:
    0
    Views:
    330
    zorhel
    Aug 24, 2004
  2. Bob
    Replies:
    24
    Views:
    1,546
  3. zorhel
    Replies:
    0
    Views:
    124
    zorhel
    Aug 24, 2004
  4. zorhel
    Replies:
    0
    Views:
    127
    zorhel
    Aug 24, 2004
  5. Stefan Mueller
    Replies:
    7
    Views:
    132
Loading...

Share This Page