Cross-Browser Mouse Event Handling

Discussion in 'Javascript' started by Martin Rinehart, Feb 2, 2009.

  1. Martin Rinehart, Feb 2, 2009
    #1
    1. Advertising

  2. Martin Rinehart wrote:
    > I have written a short article on handling mouse events in a standards-
    > based, cross-browser way. It's here:
    >
    > http://www.martinrinehart.com/examples/cross-browser-mouse-events.html
    >
    > Sadly, quirksmode.org is quite obsolete on this subject.


    Why is it that so often clueless wannabes think they need to write
    *articles* about those subjects? Example:

    | 1. Never assign event handlers in your markup. Assign functions via
    | JavaScript.
    |
    | Wrong:
    | <tag id='myObject' onclick='myOnClickHandler()'>
    |
    | Right:
    | obj = document.getElementById( 'myObject' );
    | obj.onclick=myClickHandler; // no parens

    That is utter nonsense already. Using methods to retrieve element object
    references, particularly untested ones without fallback, and then even
    proprietary event handler properties referring to global functions is *way*
    more problematic (as in: not interoperable, having side effects aso.) than a
    standards-compliant event-handler attribute.

    NOT recommended.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #2
    1. Advertising

  3. Martin Rinehart

    Doug Gunnoe Guest

    On Feb 2, 12:11 pm, Martin Rinehart <> wrote:
    > I have written a short article on handling mouse events in a standards-
    > based, cross-browser way. It's here:
    >
    > http://www.martinrinehart.com/examples/cross-browser-mouse-events.html
    >
    > Sadly, quirksmode.org is quite obsolete on this subject.


    You said:
    1. Never assign event handlers in your markup. Assign functions via
    JavaScript.
    Wrong:
    <tag id='myObject' onclick='myOnClickHandler()'>

    So, why is it "wrong"? “Wrong” is kind of strong don’t you think?
    Wouldn’t it be better to say “preferred”?
     
    Doug Gunnoe, Feb 2, 2009
    #3
  4. Thomas 'PointedEars' Lahn wrote:
    > Martin Rinehart wrote:
    >> I have written a short article on handling mouse events in a standards-
    >> based, cross-browser way. It's here:
    >>
    >> http://www.martinrinehart.com/examples/cross-browser-mouse-events.html
    >> [...]

    >
    > [...]
    >
    > | 1. Never assign event handlers in your markup. Assign functions via
    > | JavaScript.
    > |
    > | Wrong:
    > | <tag id='myObject' onclick='myOnClickHandler()'>
    > |
    > | Right:
    > | obj = document.getElementById( 'myObject' );
    > | obj.onclick=myClickHandler; // no parens
    >
    > [...]
    > NOT recommended.


    Correction: Recommended AGAINST.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #4
  5. Doug Gunnoe wrote:
    > On Feb 2, 12:11 pm, Martin Rinehart <> wrote:
    >> http://www.martinrinehart.com/examples/cross-browser-mouse-events.html
    >> [...]

    >
    > You said:
    > 1. Never assign event handlers in your markup. Assign functions via
    > JavaScript.
    > Wrong:
    > <tag id='myObject' onclick='myOnClickHandler()'>
    >
    > So, why is it "wrong"? “Wrong†is kind of strong don’t you think?
    > Wouldn’t it be better to say “preferred�


    If yes, *why*, given the *more* compatible and *more* reliable alternative
    that has *less* side effects?


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #5
  6. Martin Rinehart

    Erwin Moller Guest

    Martin Rinehart schreef:
    > I have written a short article on handling mouse events in a standards-
    > based, cross-browser way. It's here:
    >
    > http://www.martinrinehart.com/examples/cross-browser-mouse-events.html
    >
    > Sadly, quirksmode.org is quite obsolete on this subject.


    Hi Martin,

    Nice article. Nice simple easy-to-understand fix-up routine as far as I
    can judge.

    I have one remark: You start with the following:

    But you don't explain that at all.
    I have no clue why you state that so boldly.
    I use eventhandlers everywhere in my code in the way you call wrong, and
    never had much trouble with them. ;-)

    So maybe you could add a few thoughts about that too?


    Regards,
    Erwin Moller


    --
    "There are two ways of constructing a software design: One way is to
    make it so simple that there are obviously no deficiencies, and the
    other way is to make it so complicated that there are no obvious
    deficiencies. The first method is far more difficult."
    -- C.A.R. Hoare
     
    Erwin Moller, Feb 2, 2009
    #6
  7. Martin Rinehart

    Doug Gunnoe Guest

    On Feb 2, 12:25 pm, Thomas 'PointedEars' Lahn <>
    wrote:

    > If yes, *why*, given the *more* compatible and *more* reliable alternative
    > that has *less* side effects?
    >
    > PointedEars


    I can see where either way could be more convenient given a particular
    situation, but I agree with you that the OP's characterization of it
    being 'wrong' is strange.

    And he starts off with a negative comment about quirksmode…??
     
    Doug Gunnoe, Feb 2, 2009
    #7
  8. Doug Gunnoe wrote:
    > Thomas 'PointedEars' Lahn wrote:
    >> If yes, *why*, given the *more* compatible and *more* reliable alternative
    >> that has *less* side effects?
    >> [...]

    >
    > I can see where either way could be more convenient given a particular
    > situation, but I agree with you that the OP's characterization of it
    > being 'wrong' is strange.


    ACK

    > And he starts off with a negative comment about quirksmode…??


    The documentation on quirksmode.org is far from being perfect, indeed.
    However, with a level of "knowledge" such as this, one better avoids
    commenting on that.

    When replying, retain the context of the quote and don't quote signatures,
    please.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #8
  9. kangax wrote:
    > Thomas 'PointedEars' Lahn wrote:
    >> Martin Rinehart wrote:

    > [...]
    >> | 1. Never assign event handlers in your markup. Assign functions via
    >> | JavaScript.
    >> |
    >> | Wrong:
    >> | <tag id='myObject' onclick='myOnClickHandler()'>
    >> |
    >> | Right:
    >> | obj = document.getElementById( 'myObject' );
    >> | obj.onclick=myClickHandler; // no parens
    >>
    >> That is utter nonsense already. Using methods to retrieve element object
    >> references, particularly untested ones without fallback, and then even
    >> proprietary event handler properties referring to global functions is *way*
    >> more problematic (as in: not interoperable, having side effects aso.) than a
    >> standards-compliant event-handler attribute.

    >
    > But don't event handler attributes have their own problems - notably a
    > somewhat idiotic scope augmentation?


    Are you confusing markup attributes and script properties? -v please

    > Wouldn't it be recommended to use something along these lines:
    >
    > (function(){
    > ...
    > var obj = document.getElementById('myObject');
    > if (obj) {
    > obj.onclick = someHandler;
    > }
    > ...
    > })();


    Of course not. Why?

    > On a side note, looks like author forgot to declare that `obj`.


    And he is assigning to host object's properties among all kinds of other
    blunders.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #9
  10. kangax wrote:
    > Thomas 'PointedEars' Lahn wrote:
    >> kangax wrote:
    >>> But don't event handler attributes have their own problems - notably a
    >>> somewhat idiotic scope augmentation?

    >> Are you confusing markup attributes and script properties? -v please

    >
    > I was referring to intrinsic event attributes [1] which augment created
    > functions with: element, (possibly) containing form element and document
    > element objects.


    How did you get that idea? Which functions?

    <...
    onclick="handleClick(typeof event != 'undefined' ? event : null, this)"
    >...</...>


    and similar works fine (albeit the value of `event' and `this' is somewhat
    proprietary behavior), and the Function object referred to by `handleClick'
    isn't augmented with anything.

    > AFAIK, this doesn't happen when assigning event handlers directly to
    > element properties ( as in, `myElement.onclick = myHandler` ).


    In contrast, those element *object* properties are host-defined, and
    completely proprietary. Chances for support are high for historical
    reasons, but they may not be interoperable.

    > I considered the latter option to be safer in this regard (no scope
    > augmentation and so less chance of hard-to-find errors).
    >
    > Am I missing something that makes former option a better candidate?


    Not writing spaghetti code, apparently.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #10
  11. kangax wrote:
    > Thomas 'PointedEars' Lahn wrote:
    >> Martin Rinehart wrote:



    >
    > But don't event handler attributes have their own problems - notably a
    > somewhat idiotic scope augmentation?
    >
    > Wouldn't it be recommended to use something along these lines:
    >


    [snip]

    The approach of assigning an event handler via script separates the
    attachment from from the content, so the script can be moved around to
    different place in the document.

    The script might want to be moved for performance reasons, to lower in
    the page, such as before the body tag, to allow the contents to render
    without being blocked by one or more top scripts.

    The article has an example of augmenting the event object:

    | if ( !e.srcElement ) { e.srcElement = e.target; }

    There might be an error if the host object does not allow such
    modification. Instead, a local variable can be used:

    var target = e.target || e.srcElement;

    (a reusable function can also do the job)


    Also:

    | Actually, no browser tested yet returns a middle button click

    javascript: void(document.onclick = function(e) {document.title=e.type;})

    CLicking on my mouse Microsoft wheel, plugged into my mac.

    Result in FF3 and Safari 3:
    document's title changes to "click"

    Write more tests that the reader can run.

    Garrett

    --
    comp.lang.javascript FAQ <URL: http://jibbering.com/faq/ >
     
    Garrett Smith, Feb 2, 2009
    #11
  12. Martin Rinehart

    JR Guest

    Hi,
    I suppose Martin Rinehart is an unobtrusive javascript evangelist (a
    Shiite maybe?). "Never assign event handlers in your markup" resembles
    "Never, under any circumstances, add Javascript directly to the
    document" from Christian Heilmann (a Yahoo javascript evangelist). I
    prefer "never say never"...

    > Sadly, quirksmode.org is quite obsolete on this subject.


    Man, this line raises antipathy on a javascript newsgroup. Peter-Paul
    Koch (ppk), John Resig, Douglas Crockford, Dean Edwards are gods for
    me...

    Cheers,
    João Rodrigues
     
    JR, Feb 2, 2009
    #12
  13. Thomas 'PointedEars' Lahn wrote:
    > kangax wrote:
    >> Thomas 'PointedEars' Lahn wrote:
    >>> kangax wrote:



    > <...
    > onclick="handleClick(typeof event != 'undefined' ? event : null, this)"
    > >...</...>

    >
    > and similar works fine (albeit the value of `event' and `this' is somewhat
    > proprietary behavior), and the Function object referred to by `handleClick'
    > isn't augmented with anything.
    >


    No, that function isn't augmented. It is the event handler content that
    is augmented. Something like:

    function onclick(event) {
    with(document) {
    with(this.form) {
    with(this) {
    // Event handler attribute value here.
    handleClick(typeof event != 'undefined' ? event : null, this);
    }
    }
    }


    Garrett

    --
    comp.lang.javascript FAQ <URL: http://jibbering.com/faq/ >
     
    Garrett Smith, Feb 2, 2009
    #13
  14. Garrett Smith wrote:
    > kangax wrote:
    >> Thomas 'PointedEars' Lahn wrote:
    >>> Martin Rinehart wrote:

    >> But don't event handler attributes have their own problems - notably a
    >> somewhat idiotic scope augmentation?
    >>
    >> Wouldn't it be recommended to use something along these lines:

    >
    > [snip]
    >
    > The approach of assigning an event handler via script separates the
    > attachment from from the content, so the script can be moved around to
    > different place in the document.


    And completely separating the function from the markup it is operating on
    (and with) is a Good Thing, because ...?

    Assigning event listeners with scripting in fact makes the code less
    reliable (because when using DOM features, there is no guarantee that and
    how they will work), less efficient (because of more feature-testing that is
    required then as script errors should be avoided), and lest you forget, it
    makes debugging a lot harder, especially with addEventListener() or
    attachEvent(). BTDT. So it should be only done when it is absolutely
    necessary. In all other cases, event-handler attributes should be used
    instead, and event bubbling should be employed where and when applicable and
    interoperable.

    > The script might want to be moved for performance reasons, to lower in
    > the page, such as before the body tag,


    Given that there is no "body tag", where do you think that is, exactly?

    > to allow the contents to render without being blocked by one or more
    > top scripts.


    The `body' element has an intrinsic standards-compliant `onload'
    event-handler attribute for that.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #14
  15. kangax wrote:
    > Thomas 'PointedEars' Lahn wrote:
    >> kangax wrote:
    >>> Thomas 'PointedEars' Lahn wrote:
    >>>> kangax wrote:
    >>>>> But don't event handler attributes have their own problems - notably a
    >>>>> somewhat idiotic scope augmentation?
    >>>> Are you confusing markup attributes and script properties? -v please
    >>> I was referring to intrinsic event attributes [1] which augment created
    >>> functions with: element, (possibly) containing form element and document
    >>> element objects.

    >> How did you get that idea? Which functions?
    >>
    >> <...
    >> onclick="handleClick(typeof event != 'undefined' ? event : null, this)"
    >> >...</...>

    >>
    >> and similar works fine (albeit the value of `event' and `this' is somewhat
    >> proprietary behavior), and the Function object referred to by `handleClick'
    >> isn't augmented with anything.

    >
    > `handleClick` is not augmented, but the Function object whose body is
    > created from the value of attribute ("onclick" in this case) is
    > augmented with both - element in question and the document (that this
    > element is contained within) -


    No, it isn't. The scope chain of the execution context is different than
    when the function was executed elsewhere (you could call that "augmented"),
    but that is to be expected. And whether it is really a Function object that
    is called remains to be seen; we are dealing with host objects here.

    > <html>
    > <head>
    > <title></title>
    > </head>
    > <body>
    > <div title="blah"
    > onclick="alert([body, title].join('\n'))">test</div>
    > </body>
    > </html>


    That's not Valid, BTW.

    > - should demonstrate the issue clearly.


    And that is a problem, because ...? As I said, simply don't write such
    spaghetti code.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #15
  16. Thomas 'PointedEars' Lahn wrote:
    > Garrett Smith wrote:
    >> kangax wrote:
    >>> Thomas 'PointedEars' Lahn wrote:
    >>>> Martin Rinehart wrote:
    >>> But don't event handler attributes have their own problems - notably a
    >>> somewhat idiotic scope augmentation?
    >>>
    >>> Wouldn't it be recommended to use something along these lines:

    >> [snip]
    >>
    >> The approach of assigning an event handler via script separates the
    >> attachment from from the content, so the script can be moved around to
    >> different place in the document.

    >
    > And completely separating the function from the markup it is operating on
    > (and with) is a Good Thing, because ...?
    >


    "so the script can be moved around to different place in the document"

    > Assigning event listeners with scripting in fact makes the code less
    > reliable (because when using DOM features, there is no guarantee that and


    Can you show us an example of the unreliability?

    > how they will work), less efficient (because of more feature-testing that is
    > required then as script errors should be avoided), and lest you forget, it
    > makes debugging a lot harder, especially with addEventListener() or
    > attachEvent(). BTDT. So it should be only done when it is absolutely
    > necessary. In all other cases, event-handler attributes should be used
    > instead, and event bubbling should be employed where and when applicable and
    > interoperable.
    >
    >> The script might want to be moved for performance reasons, to lower in
    >> the page, such as before the body tag,

    >
    > Given that there is no "body tag", where do you think that is, exactly?
    >


    <!-- here -->
    </body>
    </html>

    >> to allow the contents to render without being blocked by one or more
    >> top scripts.

    >
    > The `body' element has an intrinsic standards-compliant `onload'
    > event-handler attribute for that.
    >


    Adding a body onload event handler will not prevent the blocking nature
    of a script.


    --
    comp.lang.javascript FAQ <URL: http://jibbering.com/faq/ >
     
    Garrett Smith, Feb 2, 2009
    #16
  17. JR wrote:
    > I suppose Martin Rinehart is an unobtrusive javascript evangelist (a
    > Shiite maybe?).


    I don't suppose, I *know* he is a clueless wannabe, parroting what he has
    managed to understand (or thought he had understood), from what he has been
    posting so far. Isn't that at least the third article in a row that
    promotes practices being marked as "not recommended" and "deprecated" around
    here a long time ago?

    > "Never assign event handlers in your markup" resembles
    > "Never, under any circumstances, add Javascript directly to the
    > document" from Christian Heilmann (a Yahoo javascript evangelist). I
    > prefer "never say never"...


    ACK

    >> Sadly, quirksmode.org is quite obsolete on this subject.

    >
    > Man, this line raises antipathy on a javascript newsgroup. Peter-Paul
    > Koch (ppk), John Resig, Douglas Crockford, Dean Edwards are gods for
    > me...


    I suppose at least one of them wouldn't mind had omitted their name from
    this particular ... selection. And it seems few of them, if any, have a
    good grasp of ECMAScript *and* DOM scripting. If those are your gods, you
    better convert for your own sake ...


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #17
  18. Garrett Smith wrote:
    > Thomas 'PointedEars' Lahn wrote:
    >> Garrett Smith wrote:
    >>> kangax wrote:
    >>>> Thomas 'PointedEars' Lahn wrote:
    >>>>> Martin Rinehart wrote:
    >>>> But don't event handler attributes have their own problems - notably a
    >>>> somewhat idiotic scope augmentation?
    >>>>
    >>>> Wouldn't it be recommended to use something along these lines:
    >>> [snip]
    >>>
    >>> The approach of assigning an event handler via script separates the
    >>> attachment from from the content, so the script can be moved around to
    >>> different place in the document.

    >> And completely separating the function from the markup it is operating on
    >> (and with) is a Good Thing, because ...?

    >
    > "so the script can be moved around to different place in the document"


    You don't need to do this to have that. Besides, what are the practical
    advantages of "moving scripts around"? The mere possibility isn't enough
    to support a design decision.

    >> Assigning event listeners with scripting in fact makes the code less
    >> reliable (because when using DOM features, there is no guarantee that and

    >
    > Can you show us an example of the unreliability?


    Another?

    >> how they will work), less efficient (because of more feature-testing that is
    >> required then as script errors should be avoided), and lest you forget, it
    >> makes debugging a lot harder, especially with addEventListener() or
    >> attachEvent(). BTDT. So it should be only done when it is absolutely
    >> necessary. In all other cases, event-handler attributes should be used
    >> instead, and event bubbling should be employed where and when applicable and
    >> interoperable.
    >>
    >>> The script might want to be moved for performance reasons, to lower in
    >>> the page, such as before the body tag,

    >> Given that there is no "body tag", where do you think that is, exactly?

    >
    > <!-- here -->


    Since the parse tree is incomplete at this point, there is no guarantee that
    all required DOM objects have been created and their associations in the
    document tree have been registered. We have been over this several times
    already, apparently you have not been paying attention.

    > </body>

    ^^^^^^^
    This is the *end tag* of the *BODY/body element*. That element begins with
    its start tag, <body ...>.

    This is not a Web forum for script-kiddies, but a newsgroup for script
    programmers; learn to use proper technical terms.

    <http://www.w3.org/TR/html401/intro/sgmltut.html#h-3.2.1>

    > </html>
    >
    >>> to allow the contents to render without being blocked by one or more
    >>> top scripts.

    >> The `body' element has an intrinsic standards-compliant `onload'
    >> event-handler attribute for that.

    >
    > Adding a body onload event handler will not prevent the blocking nature
    > of a script.


    Nor will moving it within the `body' element. But if larger `script' code
    is to be loaded, it does not matter where it is loaded (unless it executes
    instead of declares, see above), for in the `onload' attribute value its
    references are available.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Feb 2, 2009
    #18
  19. Martin Rinehart

    RobG Guest

    On Feb 3, 4:11 am, Martin Rinehart <> wrote:
    > I have written a short article on handling mouse events in a standards-
    > based, cross-browser way. It's here:
    >
    > http://www.martinrinehart.com/examples/cross-browser-mouse-events.html


    The following:

    "Most browsers follow the standard, assigning a reference to the
    object on which the event occured to e.srcElement. MSIE calls this
    reference e.target, so again we're doing extra work to get MSIE
    upgraded to standard. "

    Is completely backwards - the standards compliant property is
    Event.target, the IE proprietary property is Event.srcElement.

    W3C Event.target
    <URL: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-target
    >


    MS Event.srcElement
    <URL: http://msdn.microsoft.com/en-us/library/ms534638(VS.85).aspx >

    I find it useful to always reference standards or official
    documentation where I can, that way errors are easily rectified.

    As noted by others, do not assume you can successfully modify host
    objects. If your intention is to "fix" a host object, either create
    methods that, when called, return appropriate values or your own
    object with modified properties and methods.


    > Sadly, quirksmode.org is quite obsolete on this subject.


    Feel free to contact the author and discuss that with him, he has a
    link to his (reasonably active) blog on the quirksmode home page.


    --
    Rob
     
    RobG, Feb 2, 2009
    #19
  20. Martin Rinehart

    RobG Guest

    On Feb 3, 9:54 am, "Richard Cornford" <>
    wrote:
    > Garrett Smith wrote:
    > > Thomas 'PointedEars' Lahn wrote:
    > >> Garrett Smith wrote:
    > >>> kangax wrote:
    > >>>> Thomas 'PointedEars' Lahn wrote:
    > >>>>> Martin Rinehart wrote:
    > >>>> But don't event handler attributes have their own problems
    > >>>> - notably a somewhat idiotic scope augmentation?

    >
    > >>>> Wouldn't it be recommended to use something along these lines:
    > >>> [snip]

    >
    > >>> The approach of assigning an event handler via script separates
    > >>> the attachment from from the content, so the script can be moved
    > >>> around to different place in the document.

    >
    > >> And completely separating the function from the markup it is
    > >> operating on (and with) is a Good Thing, because ...?

    >

    [...]
    >
    > <snip>>>> to allow the contents to render without being blocked by
    > >>> one or more top scripts.

    >
    > <snip>
    >
    > That story gets put about as if it is some sort of universal panacea.
    > When the contents that the reader is interested in are at the top of the
    > document then putting them where they can be read as soon as possible
    > might be a good ides. But it can be an irritating pain if what you are
    > interested in is at the bottom of the page (such as the latest comments
    > on a blog that you have already read) and the loading of the scripts at
    > the bottom of the page block the ability to scroll. In that case I would
    > rather not have the top of the page sitting there taunting me while the
    > browser is not allowing me to scroll to what I am interested in.
    >
    > It may be that the real issue is attempting to download too much script
    > code, and playing around with where that code is loaded is just playing
    > with the symptoms rather than addressing the cause.


    This philosophy has turned full circle: events added dynamically
    during the page load (so-called "unobtrusive javascript") can take so
    long that some libraries have block and unblock methods to prevent the
    user doing anything until the page is loaded and all initialising
    scripts have run.

    So much for "unobtrusive"!

    A similar model was tried in version 1 browsers over a decade ago[1]
    and rejected by users. It seems absurd that "Web 2-point-oh"
    applications are reintroducing it as a modern, useful feature when it
    is infact an indication of poor design and implementation of
    functionality.

    1. Early versions of Netscape (and probably other browsers) didn't
    show any page content until all the page content had finished loading.


    --
    Rob
     
    RobG, Feb 3, 2009
    #20
    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. TogaKangaroo
    Replies:
    2
    Views:
    2,086
    Ioannis Vranos
    Feb 12, 2005
  2. tom arnall
    Replies:
    6
    Views:
    1,293
    Ian Shef
    Jan 18, 2007
  3. John Fereira

    cross browser multipart form handling

    John Fereira, Sep 2, 2005, in forum: Javascript
    Replies:
    4
    Views:
    108
    John Fereira
    Sep 3, 2005
  4. cjl
    Replies:
    1
    Views:
    143
  5. Gregor Kofler
    Replies:
    9
    Views:
    352
    Gregor Kofler
    Oct 8, 2009
Loading...

Share This Page