David Mark's Javascript Tip of the Day - Volume #1 - #Tip 14-C

Discussion in 'Javascript' started by David Mark, Nov 8, 2011.

  1. David Mark

    David Mark Guest

    David Mark's Javascript Tip of the Day - Volume #1 - #Tip 14-C

    In an (X)HTML DOM, don't read/manipulate DOM attributes (e.g.
    "class"). Use the corresponding properties (e.g. "className"). It's
    more intuitive, with less code, less calls and no legacy IE nonsense
    (e.g. broken get/setAttribute, no hasAttribute, etc.) to worry about.
    This has been the rule forever.

    In all the time I've worked with DOM elements, there is only one
    exception that comes to mind. Something like this, IIRC:-

    var elButton = document.createElement('button');
    //elButton.type = 'button';
    elButton.setAttribute('type', 'button');

    ....was required in Webkit-based browsers at the time. From a quick
    console session, it appears this is still the case as the "type" set
    on the BUTTON fails silently, so the default of "submit" remains. Not
    sure if this is a bug or if there is an allowance for such behavior in
    the recommendation for BUTTON elements. Doesn't seem reasonable to
    make the "type" property of a button write-once unless the caller is
    afforded a chance to write it once.

    I normally use INPUT of type "button", which has no such ambiguity, so
    don't really care one way or the other. Whether due to a browser bug
    or recommendation shortcoming; it's the one time I can think of where
    I had to resort to using setAttribute in an HTML DOM operation.
    Operative word is "one". :)

    Buttons created with innerHTML will not have this problem as the
    parser will take care of setting the "type" property to "button".

    Anyway, in an XML DOM (e.g. XHR result), there are only attributes, so
    you must use the attribute-related methods.

    So there is really nothing to worry about, is there? :)

    It's unfortunate that most of the "major" JS libraries feature an
    "attr" method that attempts to deal with *both* HTML and XML (though
    not normally XHTML). Even worse, they seem to have been written with
    little understanding of the above concepts, IE bugs and shortcomings,
    etc., ending up as gobbledygook after years of guesswork and patching.

    The documentation for the recently added "prop" function demonstrates
    just how confused that effort is.


    First off, it says it returns a string. :(

    Then there's this:-

    "Concerning boolean attributes, consider a DOM element defined by the
    HTML markup <input type="checkbox" checked="checked" />, and assume it
    is in a JavaScript variable named elem:"

    The DOM element defined by the "HTML markup" is "in a JavaScript
    variable". Never mind the awkward wording and XHTML; it's clear what
    they are trying to say. But would it be clear to a beginner trying to
    forget the "troubles" of basic DOM scripting?

    And this is their result matrix:-

    elem.checked true (Boolean) Will change with
    checkbox state
    $(elem).prop("checked") true (Boolean) Will change with
    checkbox state
    elem.getAttribute("checked") "checked" (String) Initial state of the
    checkbox; does not change
    $(elem).attr("checked")(1.6) "checked" (String) Initial state
    of the checkbox; does not change
    $(elem).attr("checked")(1.6.1+) "checked" (String) Will change with
    checkbox state
    $(elem).attr("checked")(pre-1.6) true (Boolean) Changed with checkbox

    Third one down is not going to yield anything close to consistent
    results in their "core browsers". Does change too, just not by the

    After that, the wheels fall off. No mention of 1.6.2, either.


    There's no mention of how XML DOM's are handled. Certainly "prop" does
    nothing with those, yet it is often pitched as a "better" replacement
    for "attr". The "attr" method requires *attribute* names (as it
    sometimes uses attribute-related methods). The "prop" method requires
    property names. Studying such "documentation" and following such
    recommendations will only lead to worse confusion.


    What could be the effect of all this waffling on plug-ins, widgets and
    such? The effect on the libraries is to cause them to scrap their
    previous efforts and start anew. jQuery has indicated they are going
    down that path too. Of course, there's nothing good down that path;
    will divide the project in two, sapping any momentum it had left. :(

    David Mark, Nov 8, 2011
    1. Advertisements

  2. I tried dropping gentle hints. Obviously there's some high density
    material in your skull.

    We have a faq server, we have Thomas 'pointed ears' Lahn, we don't need a
    (nother) self appointed wannabe guru trying to build a rep by spouting
    twaddle that we're not interested in reading on a daily basis.


    Denis McMahon
    Denis McMahon, Nov 8, 2011
    1. Advertisements

  3. The indexing of this new "service" is confusing. Could you please
    explain it?

    So far we have had:

    Volume 1 - Tip 1 ---------David Mark 5th Nov.2011
    Volume 1 - Tip 3A --------David Mark 7th Nov.2011
    Volume #1 - #Tip 14-C ----David Mark 8th Nov.2011
    SteveYoungTbird, Nov 8, 2011
  4. David Mark

    David Mark Guest

    It's designed to confuse morons. ;)
    David Mark, Nov 8, 2011
  5. David Mark

    David Mark Guest

    Who the hell is "we"? I own this dump. ;)
    David Mark, Nov 8, 2011
  6. It is spelled _FAQ_, and the server is frequently down, unfortunately.
    Also, I do not think that the FAQ covers this subject.

    I value David's pointing out that the Webkit bug with dynamically created
    `button' elements can be worked around with setAttribute(), as I had
    problems with that when creating widgets (for a quick solution I had opted
    to use `input[type="button"]' elements instead of `button' elements, but the
    latter are more flexible).

    Also, it is important to realize that the value of an attribute as retrieved
    with getAttribute() can be misleading. For a practical example, there is
    (was?) a jQuery UI component which attempted to provide a fallback for
    HTML5's type="date". But it used jQuery's attr() method for detection.
    Since the attr() method always uses the getAttribute() method in Gecko-based
    browsers, the plugin was unable to detect that Firefox did not support the
    attribute's `date' value (the attribute property yielded "text" which would
    have shown that), and that applying the fallback was indicated. As a
    result, the corresponding `input' element stopped working in Firefox (text-
    based date input impossible, as all keyboard events had been canceled by the
    plugin) until that jQuery plugin had been eliminated from the project's code
    _PointedEars_, please.
    Thomas 'PointedEars' Lahn, Nov 8, 2011
  7. David Mark

    S.T. Guest

    S.T., Nov 9, 2011
  8. David Mark

    RobG Guest

    Yes, but if you want to use non-standard attributes, get/setAttribute
    is the only way to go.

    I don't think non-standard attributes should be used, but as soon as
    the design heads down that route, get/setAttribute looms large.

    Also, there seem to be many programmers from other languages who like
    using a function call like get/setAttribute rather than direct
    property access. It seems to give them comfort and is a difficult
    habit to shake.

    Unfortunately the authors of various W3C specifications haven't made
    life any easier with their muddled handling of the issue. HTML5 only
    makes it worse, particularly as it introduces a heap of new
    attributes. Anyone using them will prefer get/setAttribute to property
    access to deal with older browsers where:


    "works" but


    does not.
    RobG, Nov 9, 2011
  9. David Mark

    Erwin Moller Guest

    Denis, I, for one, like to read David's contributions.
    He is an experienced Javascript/DOM programmer, hence I learn a lot (and
    get warned for shitty practices) simply reading his posts.
    I am glad David decided to participate more actively in this newsgroup

    And Thomas Lahn? When he has a good day, and takes the time to explain
    something in detail, his post are very worth your while.
    (Or at least my while.)

    You are of course entitled to your own opinion, but don't say "we",
    since that clearly doesn't include all lurkers/posters in here.

    And one last thing: Why would you object to anybody writing a
    daily/weekly/whatever opinion in here?
    It keeps usenet alive. :)
    I applaud the initiative.

    Erwin Moller
    Erwin Moller, Nov 9, 2011
  10. David Mark

    Scott Sauyet Guest

    I know you've been around long enough to recognize that David Mark is
    not new here. His posts are often repetitive, self-aggrandizing, and
    bullying, but there is also a lot of useful content in them. His
    manner is among the most obnoxious I've seen on USENET, and I've given
    up on responding to him (a fact he celebrated [1].) But I'm not sorry
    to have him participate here. When he does respond to requests for
    help (as opposed to his more common messages promoting his library or
    denigrating all others), he often does so with some skill and with
    genuinely helpful responses.

    If you're interested in discussions where his usual bluster is not
    welcomed, try JSMentors. The discussion there is much more civilized,
    generally helpful, and often more interesting than what's here. Some
    of the more interesting and helpful participants from
    comp.lang.javascript also participate there. But I find there is
    still much to learn here and many fascinating dialogs, if you can
    stomach the nonsense.

    -- Scott

    [1] http://groups.google.com/group/comp.lang.javascript/msg/2f0d6233dd2c8bf6
    Scott Sauyet, Nov 9, 2011
  11. Right, but a little bit of research by these hypothetical developers
    would reveal that the `dataset` object [0] houses connections to data-*
    attributes. Ergo, the `data-bar` attribute in `<div
    data-bar="true"></div>` would be accessed via `[Element].dataset.bar`.

    Matt McDonald, Nov 9, 2011
  12. David Mark

    Tim Down Guest

    Another exception is getting hold of a property of a <form> element
    such as "action" or "method" when a form input with the corresponding
    name exists. The input wins.

    <form id="test" action="somepage.html">
    <input name="action" value="foo">

    var form = document.getElementById("test");

    form.action is a reference to the <input> element.
    form.getAttribute("action") is "somepage.html", except in older IE
    with its broken getAttribute().

    Tim Down, Nov 9, 2011
  13. David Mark

    RobG Guest

    It will be quite some time before that feature is sufficiently well
    supported that it can be used without feature testing and fall-back to
    getAttribute, something like:

    if (element.dataset) {
    } else {
    alert(element.getAttribute('data-' + dataAtt));

    Since getAttribute works everyhwere (in regard to data- attributes at
    least), it seems a better option to dispense with the feature test and
    just use getAttribute.

    Host objects have some quirks still, in Chrome 15:


    reports in the console:

    Uncaught TypeError: Cannot convert object to primitive value
    RobG, Nov 9, 2011
  14. David Mark

    David Mark Guest

    In other words, you have no idea what you are talking about (and are
    relatively new around here).
    You are just pissed that your constant advice to use things like Dojo
    and jQuery turned out so badly.
    I'll see you over there. ;) Hope you aren't doing your usual act.
    ....And the stalkers. Get a life.
    David Mark, Nov 10, 2011
  15. David Mark

    David Mark Guest

    Yes, so the best bet is not to name form controls "action" (or
    anything else that clashes with properties of the form object).
    David Mark, Nov 10, 2011
  16. David Mark

    David Mark Guest

    Absolutely as there are no corresponding properties.
    Right. Will create expando properties in IE5-7 (and compatibility
    mode), but there's nothing that can be done for that.
    Yes and all of the ridiculous library "attr" functions and their bad
    documentation aren't helping at all.
    Yes, hyphenated attribute names have traditionally been reflected by
    camel-case property names. I assume the data-whatever attributes are
    not reflected and should therefore be handled like custom attributes.

    And HTML5 really screwed up the naming as well (DOM properties are now
    some sort of attributes apparently). Given that for several years,
    the most "advanced" JS efforts out there couldn't tell attributes from
    properties, what chance will beginners have if both are now called
    David Mark, Nov 10, 2011
  17. David Mark

    Scott Sauyet Guest

    I'm curious as to why. (I know that I once accused you of being a
    David Mark pseudonym, and I know that some might find that insulting,
    but you are clearly a fan, so I can't imagine you're terribly
    offended.) I've been reading this group two years and posting two
    months less. In that time, there is only one person who has publicly
    suggested that my contributions were inappropriate or that my effect
    on the group was less than salubrious. That was David Mark, of
    course. Now he's accusing me of promoting jQuery, Dojo, etc, which is
    not at all what I've posted. But if he stays true to form, he'll keep
    saying it, acting as though if he says it enough, it'll be true.

    Except when seriously provoked, I'm fairly mild-mannered in my
    posting. David Mark, on the other hard, obviously works to draw
    attention to himself, and has drawn the ire of many here in the
    process. As I said earlier, I wish he was less abrasive and less
    abusive. But I do think that he has also made significant positive
    contributions in the time I've been watching.

    -- Scott
    Scott Sauyet, Nov 11, 2011
    1. Advertisements

Ask a Question

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

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