MSIE Does Not Do OnMouseXXX Events On Span Elements?

Discussion in 'Javascript' started by mavigozler, Apr 12, 2007.

  1. mavigozler

    mavigozler Guest

    IE7 does not appear to set an event on contained text inside SPAN elements
    whose 'onclick', 'onmouseover', and 'onmouseout' events, defying the HTML
    recommendation. Firefox appears to conform.

    Is that so?
     
    mavigozler, Apr 12, 2007
    #1
    1. Advertising

  2. mavigozler

    Elegie Guest

    mavigozler wrote:

    Hi,

    > IE7 does not appear to set an event on contained text inside SPAN elements
    > whose 'onclick', 'onmouseover', and 'onmouseout' events, defying the HTML
    > recommendation. Firefox appears to conform.


    <span onmouseover="this.innerHTML=new Date()">Hello, World</span>

    .... works fine on IE7, could you post a simple test case demonstrating
    your issue? Thanks.
     
    Elegie, Apr 12, 2007
    #2
    1. Advertising

  3. mavigozler

    mavigozler Guest

    Elegie <> wrote in comp.lang.javascript:

    > mavigozler wrote:
    >
    > Hi,
    >
    >> IE7 does not appear to set an event on contained text inside SPAN
    >> elements whose 'onclick', 'onmouseover', and 'onmouseout' events,
    >> defying the HTML recommendation. Firefox appears to conform.

    >
    > <span onmouseover="this.innerHTML=new Date()">Hello, World</span>
    >
    > ... works fine on IE7, could you post a simple test case demonstrating
    > your issue? Thanks.


    I forgot to add that the SPAN element is dynamically added to the
    document. I am creating a document that dynamically adds text to the
    document, and I want that text to be highlighted when the mouse is over
    it, so the text is contained within a SPAN element. Note that I clone a
    template span node whenever I need it, with the attributes for
    "onmouseover" and "onmouseout" set to highlight and un-highlight text,
    respectively.

    A working example with validated HTML is below. Works in Firefox, but not
    in IE7 (browser object embedded in Firefox).


    ========== Interactive HTML document start ================

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
    "http://www.w3.org/TR/REC-html40/loose.dtd">
    <html>
    <head>
    <title>Mouseover Dynamic SPAN Element</title>
    <script type="text/javascript">
    var spanElemTemplate = document.createElement("span");
    spanElemTemplate.setAttribute("style", "border:1px solid green;");
    spanElemTemplate.setAttribute("onmouseover", "hiliteText(this, true);");
    spanElemTemplate.setAttribute("onmouseout", "hiliteText(this, false);");

    function hiliteText(spanObj, status)
    {
    if (status == true)
    // yellow text hilite
    spanObj.style.backgroundColor = "yellow";
    else
    spanObj.style.backgroundColor = "";
    /* note that spanObj.setAttribute("style",
    "background-color:yellow"); also works in FF */
    }

    function insertSpan()
    {
    var insertPoint = document.getElementById("insert-span-here");
    var templateInstance = spanElemTemplate.cloneNode(true);
    templateInstance.appendChild(document.createTextNode(
    "This text should turn yellow when the mouse is over it"));
    insertPoint.appendChild(templateInstance);
    }

    </script>
    </head>
    <body>

    <button onclick="insertSpan();">Insert span element example</button>
    <p>
    Span element is inserted below:
    <p id="insert-span-here">

    </body>
    </html>

    ========== Interactive HTML document end ================
     
    mavigozler, Apr 14, 2007
    #3
  4. mavigozler

    Elegie Guest

    mavigozler wrote:

    Hi,

    <snip>

    > Note that I clone a
    > template span node whenever I need it, with the attributes for
    > "onmouseover" and "onmouseout" set to highlight and un-highlight text,
    > respectively.


    While this approach is certainly sound theoretically, it should actually
    fail. I am unsure about which observed behavior is the correct one,
    given the existing specifications, or what the actual mechanisms
    implemented by user agents are; what follows is just some personal
    interpretation (corrections welcome).

    In HTML, you can define event attributes, such as onmouseover,
    onmouseout. However, these are special, as they should translate into
    event listeners, at parsing time. As a result, should they still be
    considered as attributes? Probably not, though one could probably keep
    some simple text attribute for the record. And if they're not
    attributes, they should not be cloneable.

    So your problem is the combined use of setAttribute and cloneNode.
    Defining a string to be implicitly transformed into listeners by the
    browser is risky; while it works in Firefox, it does not in IE.
    Generally, we never use setAttribute for event listeners, but rather
    event-specific methods (such as addEventListener, attachEvent, or even
    the simple elem.on<event>) - actually we never use it at all in HTML
    scripting.

    As a result, refine your pattern; it would be better to use some
    factory, which would create the element, fill in the properties, and
    assign the listeners.

    > if (status == true)


    if(status) is better, and a conditional (?:) statement would be even
    better here.


    HTH,
    Elegie.
     
    Elegie, Apr 14, 2007
    #4
  5. mavigozler

    RobG Guest

    On Apr 15, 6:16 am, Elegie <> wrote:
    > mavigozler wrote:
    >
    > Hi,
    >
    > <snip>
    >
    > > Note that I clone a
    > > template span node whenever I need it, with the attributes for
    > > "onmouseover" and "onmouseout" set to highlight and un-highlight text,
    > > respectively.

    >
    > While this approach is certainly sound theoretically, it should actually
    > fail. I am unsure about which observed behavior is the correct one,
    > given the existing specifications, or what the actual mechanisms
    > implemented by user agents are; what follows is just some personal
    > interpretation (corrections welcome).
    >
    > In HTML, you can define event attributes, such as onmouseover,
    > onmouseout. However, these are special, as they should translate into
    > event listeners, at parsing time. As a result, should they still be
    > considered as attributes? Probably not, though one could probably keep
    > some simple text attribute for the record. And if they're not
    > attributes, they should not be cloneable.


    I think they are and should be cloneable - but maybe that's just me.


    > So your problem is the combined use of setAttribute and cloneNode.
    > Defining a string to be implicitly transformed into listeners by the
    > browser is risky; while it works in Firefox, it does not in IE.
    > Generally, we never use setAttribute for event listeners, but rather
    > event-specific methods (such as addEventListener, attachEvent, or even
    > the simple elem.on<event>) - actually we never use it at all in HTML
    > scripting.


    The problem is cloning nodes with event handlers - I'd previously
    discovered that with in-line hanlders, IE and Firefox keep them when
    nodes are cloned. When added to the dot property ( el.onclick =
    function(){...}; or = someFn;) both will drop the handler from cloned
    nodes. But for attachEvent/addEventListener, IE keeps them and
    Firefox drops them.

    So it depends on how you add the handler and which browser you are
    using. I haven't time to test other browsers at the moment, nor have
    I tested adding handlers with setAttribute (I never use that method of
    adding hanlders, I nearly always use the dot property method).


    --
    Rob
     
    RobG, Apr 14, 2007
    #5
  6. mavigozler

    mavigozler Guest

    "RobG" <> wrote in comp.lang.javascript:

    > On Apr 15, 6:16 am, Elegie <> wrote:
    >> mavigozler wrote:
    >>
    >> Hi,
    >>
    >> <snip>
    >>
    >> > Note that I clone a
    >> > template span node whenever I need it, with the attributes for
    >> > "onmouseover" and "onmouseout" set to highlight and un-highlight
    >> > text, respectively.

    >>
    >> While this approach is certainly sound theoretically, it should
    >> actually fail. I am unsure about which observed behavior is the
    >> correct one, given the existing specifications, or what the actual
    >> mechanisms implemented by user agents are; what follows is just some
    >> personal interpretation (corrections welcome).
    >>
    >> In HTML, you can define event attributes, such as onmouseover,
    >> onmouseout. However, these are special, as they should translate into
    >> event listeners, at parsing time. As a result, should they still be
    >> considered as attributes? Probably not, though one could probably
    >> keep some simple text attribute for the record. And if they're not
    >> attributes, they should not be cloneable.

    >
    > I think they are and should be cloneable - but maybe that's just me.
    >
    >
    >> So your problem is the combined use of setAttribute and cloneNode.
    >> Defining a string to be implicitly transformed into listeners by the
    >> browser is risky; while it works in Firefox, it does not in IE.
    >> Generally, we never use setAttribute for event listeners, but rather
    >> event-specific methods (such as addEventListener, attachEvent, or
    >> even the simple elem.on<event>) - actually we never use it at all in
    >> HTML scripting.

    >
    > The problem is cloning nodes with event handlers - I'd previously
    > discovered that with in-line hanlders, IE and Firefox keep them when
    > nodes are cloned. When added to the dot property ( el.onclick =
    > function(){...}; or = someFn;) both will drop the handler from cloned
    > nodes. But for attachEvent/addEventListener, IE keeps them and
    > Firefox drops them.
    >
    > So it depends on how you add the handler and which browser you are
    > using. I haven't time to test other browsers at the moment, nor have
    > I tested adding handlers with setAttribute (I never use that method of
    > adding hanlders, I nearly always use the dot property method).


    First, my thanks for the contributions of posters Elegie and RobG in
    particular, and generally to those reading & joining the thread.

    Based on the comments of Elegie and RobG, I continued playing around
    with the code, and the validated interactive HTML code below appears to
    achieve the wanted effect.

    Some notes:

    1. This particular re-coding I have done now attaches method (event
    handler/listener) code to each dynamically created SPAN element, so if
    as many as hundreds of SPAN elements are attached, I have no idea what
    effect this will have on the memory heap (?) or stack (?) of the
    browser's host resources. Fortunately for my use, which is to create a
    development environment using an interactive HTML document to teach,
    build/create and render both VML and SVG elements/objects, I don't
    anticipate this problem.

    For the sake of keeping resource (memory stack and/or heap) use to a
    mimumum, it would be useful to also see if cloned elements could have
    static functions assigned to event handlers, since this should (would?)
    stop the interpreter from generating method code for each new object
    instance. However the IE-specific attachEvent() and DOM-defined
    addEventListener() methods do not allow the passing of parameters, and
    the 'this' keyword to change object properties only works in Firefox and
    causes an error in IE7, in the hour-or-so code testing I did.

    Would some sort of use of prototyping be possible in this case?

    2. The cloning of nodes, deep (set true) or otherwise, appears to clone
    the attributes of those elements in Firefox but NOT in Internet
    Explorer. Mozilla makes clear that the node cloning method includes
    attributes and values of all nodes
    (http://developer.mozilla.org/en/docs/DOM:element.cloneNode). The DOM
    L2 specification requires this
    (http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-3A0ED0A4). The
    question is whether an event on a specific DOM element is really an
    attribute. The HTML 4.01 specificiation clearly indicates that events
    (onclick, onmouseXXX, etc) ARE attributes of elements, so in the absence
    of any overriding/obsoleting specification, developers of script
    interpreters not treating events as element attributes nor copying these
    attributes in node cloning are not conforming to the specification. XML
    documents which discuss how to incorporate event listening into the
    object tree also refer to event handling specific to a node as an
    attribute of that node, and one XML document notes that HTML document
    "unfortunately" define events listeners as attributes of elements
    (http://www.w3.org/TR/xml-events/).

    As evidence that MSIE refuses to clone any attributes whatsoever and not
    just those that event handlers/listeners, the 1 pixel green border is
    not rendered at all in the cloning of the SPAN element, whereas Firefox
    goes out of its way (in conforming to the specification?) in doing so,
    as with the event handlers.


    ========= start validated interactive HTML code ==========

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
    "http://www.w3.org/TR/REC-html40/loose.dtd">

    <html>
    <head>
    <title>Mouseover Dynamic SPAN Element</title>
    <script type="text/javascript">
    var spanElemTemplate = document.createElement("span");
    spanElemTemplate.setAttribute("style", "border:1px solid green;");

    function insertSpan()
    {
    var insertPoint = document.getElementById("insert-span-here");
    var templateInstance = spanElemTemplate.cloneNode(true);
    templateInstance.onmouseover = function () {
    this.style.backgroundColor = "yellow";
    };
    templateInstance.onmouseout = function () {
    this.style.backgroundColor = "";
    };
    templateInstance.appendChild(document.createTextNode(
    "This text should " +
    "turn yellow when the mouse is over it"));
    insertPoint.appendChild(templateInstance);
    }

    </script>
    </head>
    <body>

    <button onclick="insertSpan();">Insert span element example</button>
    <p>
    Span element is inserted below:
    <p id="insert-span-here">

    </body>
    </html>

    ========= end validated interactive HTML code ==========
     
    mavigozler, Apr 15, 2007
    #6
  7. mavigozler

    Elegie Guest

    mavigozler wrote:

    Hi,

    > 1. This particular re-coding I have done now attaches method (event
    > handler/listener) code to each dynamically created SPAN element, so if
    > as many as hundreds of SPAN elements are attached, I have no idea what
    > effect this will have on the memory heap (?) or stack (?) of the
    > browser's host resources.


    Instead of defining anonymous functions in the insertSpan function, you
    could define two generic handlers outside of the function, and simply
    assign references to them. This way, you'd limit the number of functions
    to be created.

    function mouseoverhandler(evt){/*...*/}
    function insertSpan() {
    /*...*/
    foo.onmouseover=mouseoverHandler;
    }


    Also, JFTR, ECMAScript permits an implementation to join identical
    function objects into a single function object. While the details of
    this process are not specified, most clever implementations would
    certainly try and join functions where possible (if the only difference
    is a matter of scope, then it should be pretty feasible, that's the
    principle of closures, working with couples {scope; function pointer}).

    > However the IE-specific attachEvent() and DOM-defined
    > addEventListener() methods do not allow the passing of parameters, and
    > the 'this' keyword to change object properties only works in Firefox and
    > causes an error in IE7, in the hour-or-so code testing I did.


    That is a known IE issue with attachEvent, the "this" value refers to
    the global object; instead of using directly the "this" keyword, you
    could probably use
    evt=evt||window.event;
    elem=evt.srcElement||evt.target;

    However, not using attachEvent is probably best when you do not have
    more than one handlers to add, elem.on<event>=handler suffices. Also,
    other patterns exist, still using elem.on<event>=handler, but permitting
    many handlers (for instance keeping them into an array and having a
    controller execute them, or stacking the handlers with closures).

    > 2. The cloning of nodes, deep (set true) or otherwise, appears to clone
    > the attributes of those elements in Firefox but NOT in Internet
    > Explorer.


    The situation is more complex than that, browsers' behaviors are simply
    not consistent in regards of methods setAttribute and cloneNode, and the
    specifications are (IMHO) too blurry to really tell who's right. Anyway,
    in the end, only the result matters, so the conclusion is: use these
    methods with care (or, better, adopt a safer approach, with other
    approaches), after thoughtful testing in your target environments.

    Let's discuss this a bit more. If you read the DTD, you'll see that
    values for HTML attributes eventually resolve to text values, not
    objects. However, using the DOM, we can see that elem.onevent returns a
    function, and that elem.style returns an object.

    This means that, during the parsing, the text attributes have been
    transformed into objects, with a specific process (this process not
    being described by any specification I think, though since it's been
    years I haven't read them I might be mistaken).

    For instance, event attributes would yield event listeners, and style
    attributes would transform into an object representing the HTML style
    attribute, whose property setting alters the computed style of the object.

    In IE, setAttribute does not seem to trigger the process that transform
    text values into objects; this means that you cannot use setAttribute to
    define event handlers or style values with IE. In Firefox and Opera,
    this works, though.

    ---
    <form action=""><textarea rows="30" cols="40"></textarea></form>
    <script type="text/javascript">
    window.onload=function(evt){
    function out(s){
    document.forms[0][0].value += s+"\n";
    }

    // Test 1 - setAttribute
    var div=document.createElement("div") ;
    div.setAttribute("id", "foo");
    div.setAttribute("foo", "bar");
    div.setAttribute("style", "background-color:yellow");
    div.setAttribute("onclick","alert('click')");

    div.appendChild(document.createTextNode("Hello, world!"));
    document.body.appendChild(div);

    out("Id? " + (document.getElementById("foo")==div));
    out("custom foo? " + (div.getAttribute("foo")=="bar"));
    out("onclick? " + (typeof div.onclick=="function"));
    out("style? " + div.style.backgroundColor);

    /*
    IE : true, true, false, <empty>
    FF : true, true, true, yellow
    Opera : true, true, true, #ffff00

    Note: if div.foo instead of div.getAttribute(foo),
    results differ.
    */
    }
    </script>
    ---

    Now, suppose that you remove the setAttribute issue, by directly working
    with objects (you can even remove the style issue by using a className).
    In IE, the cloneNode method clones everything except HTML event handlers
    (listeners attached with attachEvent are fine). Firefox and Opera copy
    everything, except event listeners (all of them) and expando (custom)
    attributes.

    ---
    <form action=""><textarea rows="30" cols="40"></textarea></form>
    <script type="text/javascript">
    window.onload=function(evt){
    function out(s){
    document.forms[0][0].value += s+"\n";
    }

    // Test 2 - cloneNode
    var div=document.createElement("div"), copy ;
    div.id="foo";
    div.foo="bar";
    div.obj={hello:"Success"};
    div.style.backgroundColor="yellow";
    div.onclick=new Function("alert('click!')");
    if(div.attachEvent) {
    div.attachEvent("onclick", function(){alert('1')});
    } else if (div.addEventListener) {
    div.addEventListener("click", function(){alert('1')}, false);
    }
    div.appendChild(document.createTextNode("Hello, world!"));

    copy=div.cloneNode(true);
    document.body.appendChild(copy);

    out("Id? " + (document.getElementById("foo")==copy));
    out("custom foo? " + (copy.getAttribute("foo")=="bar"));
    out("object value? " + (copy.obj && copy.obj.hello));
    out("onclick? " + (typeof copy.onclick=="function"));
    out("style? " + (copy.style.backgroundColor));

    /*
    IE : true, true, success, false, yellow,
    FF : true, false, undefined, false, yellow
    Opera : true, false, undefined, false, #ffff00

    event listeners defined with attachEvent and addEventListener :
    IE : copied
    FF : not copied
    Opera : not copied
    */
    }
    </script>
    ---

    > The
    > question is whether an event on a specific DOM element is really an
    > attribute. The HTML 4.01 specificiation clearly indicates that events
    > (onclick, onmouseXXX, etc) ARE attributes of elements, so in the absence
    > of any overriding/obsoleting specification, developers of script
    > interpreters not treating events as element attributes nor copying these
    > attributes in node cloning are not conforming to the specification.


    <URL:http://www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/>
    does not, AFAICS, mention the handling of HTML events or style
    attributes, which is what matters here.


    Regards,
    Elegie.
     
    Elegie, Apr 15, 2007
    #7
    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. Fulio Open

    Can span include span?

    Fulio Open, Jun 26, 2009, in forum: HTML
    Replies:
    5
    Views:
    581
    dorayme
    Jun 26, 2009
  2. Stéphane Klein
    Replies:
    2
    Views:
    1,867
    John Nagle
    Mar 30, 2010
  3. Stefan Behnel
    Replies:
    0
    Views:
    507
    Stefan Behnel
    Mar 29, 2010
  4. Dan Bishop

    DataGrid (body only) contained in <span>...</span> tags

    Dan Bishop, Jun 7, 2004, in forum: ASP .Net Datagrid Control
    Replies:
    2
    Views:
    309
    Kilic Beg
    Jun 7, 2004
  5. Wang, Jay
    Replies:
    5
    Views:
    525
    Wang, Jay
    May 25, 2004
Loading...

Share This Page