getAttribute question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • RobG

    getAttribute question

    I have always accessed attributes such as disabled using the DOM
    element property, however I was wondering about implementing a more
    generic function to get the values of attributes - which of course
    leads to the DOM Element Interface's getAttribute method:

    <URL: http://www.w3.org/TR/DOM-Level-2-Cor...ml#ID-666EE0F9 >

    The DOM 2 Core specification says that getAttribute should return the
    value of an attribute as a string, however attributes such as
    disabled, checked, readonly, etc. don't have values specified in the
    HTML specification, it just specifies a behaviour if the attribute is
    present or not. The DOM HTML spec says that such attributes should
    return true or false, e.g. Inteface HTMLInputElemen t:

    <URL: http://www.w3.org/TR/DOM-Level-2-HTM...ml#ID-50886781 >

    My interpretation is that if the attribute is accessed as a property
    of a DOM element (e.g. someElement.dis abled), it should return:

    1. boolean true if the element has the attribute set in the markup
    or
    it has been set to true by script
    2. boolean false only if the attribute value has been set to false
    by script
    3. null if the attribute is not in the markup and hasn't been set by
    script,
    or if the element doesn't support the attribute

    That way the value of the DOM property can be easily converted to an
    equivalent string simply by using the returned object's toString
    method ('true', 'false' and '' respectively) which seems to fit the
    specification for getAttribute.

    I don't know of a browser that behaves as described above, they all
    have foibles. If I were to write a generic getAttributeVal ue
    function, should it behave as described above, or should it instead
    return 'disabled', '' and '' respectively? The logic could then be
    applied to other "no value" attributes such as checked, readonly and
    selected. Condition statements could be:

    if (el.getAttribut eValue('disable d') == 'true') { ... }

    which is reasonably consistent with:

    if (el.disabled) { ... }

    What do others think?


    --
    Rob
  • Janwillem Borleffs

    #2
    Re: getAttribute question

    RobG schreef:
    The DOM 2 Core specification says that getAttribute should return the
    value of an attribute as a string, however attributes such as
    disabled, checked, readonly, etc. don't have values specified in the
    HTML specification, it just specifies a behaviour if the attribute is
    present or not. The DOM HTML spec says that such attributes should
    return true or false, e.g. Inteface HTMLInputElemen t:
    >
    The common way to specify this according to the current standards is:

    <... disabled="disab led"/>

    Browsers will parse this the same way as the old notation.


    JW

    Comment

    • Thomas 'PointedEars' Lahn

      #3
      Re: getAttribute question

      RobG wrote:
      I have always accessed attributes such as disabled using the DOM
      element property, however I was wondering about implementing a more
      generic function to get the values of attributes - which of course
      leads to the DOM Element Interface's getAttribute method:
      >
      <URL: http://www.w3.org/TR/DOM-Level-2-Cor...ml#ID-666EE0F9 >
      Not necessarily. ECMAScript implementations provide the bracket property
      accessor to use variable string values as property names, and the number of
      element properties that do not match the lowercase versions of their
      attribute name is limited.

      See also http://pointedears.de/scripts/dhtml.js:setAttr()
      The DOM 2 Core specification says that getAttribute should return the
      value of an attribute as a string, however attributes such as
      disabled, checked, readonly, etc. don't have values specified in the
      HTML specification,
      Yes, they have.
      it just specifies a behaviour if the attribute is present or not.
      Not true:


      The DOM HTML spec says that such attributes should
      return true or false, e.g. Inteface HTMLInputElemen t:
      >
      <URL: http://www.w3.org/TR/DOM-Level-2-HTM...ml#ID-50886781 >
      >
      My interpretation is that if the attribute is accessed as a property
      of a DOM element (e.g. someElement.dis abled), it should return:
      >
      1. boolean true if the element has the attribute set in the markup
      or
      it has been set to true by script
      2. boolean false only if the attribute value has been set to false
      by script
      3. null if the attribute is not in the markup and hasn't been set by
      script,
      or if the element doesn't support the attribute
      Correct.
      That way the value of the DOM property can be easily converted to an
      equivalent string simply by using the returned object's toString
      method ('true', 'false' and '' respectively) which seems to fit the
      specification for getAttribute.
      Yes, you could. However, this is what setAttribute() is for.
      I don't know of a browser that behaves as described above, they all
      have foibles. If I were to write a generic getAttributeVal ue
      function, should it behave as described above,
      It should not return boolean values as content of string values.
      or should it instead return 'disabled', '' and '' respectively? The
      logic could then be applied to other "no value" attributes such as
      checked, readonly and selected. Condition statements could be:
      >
      if (el.getAttribut eValue('disable d') == 'true') { ... }
      >
      which is reasonably consistent with:
      >
      if (el.disabled) { ... }
      >
      What do others think?
      You should implement

      if (_getAttributeV alue(el, 'disabled'))

      if you don't like

      if (el.getAttribut e('disabled').t oLowerCase() == 'disabled')

      already. As you should know by now, host objects should not be tried
      to be augmented, and they cannot be prototyped universally.


      PointedEars
      --
      var bugRiddenCrashP ronePieceOfJunk = (
      navigator.userA gent.indexOf('M SIE 5') != -1
      && navigator.userA gent.indexOf('M ac') != -1
      ) // Plone, register_functi on.js:16

      Comment

      • RobG

        #4
        Re: getAttribute question

        On May 8, 10:54 pm, Thomas 'PointedEars' Lahn <PointedE...@we b.de>
        wrote:
        RobG wrote:
        I have always accessed attributes such as disabled using the DOM
        element property, however I was wondering about implementing a more
        generic function to get the values of attributes - which of course
        leads to the DOM Element Interface's getAttribute method:
        >
        <URL:http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-666EE0F9>
        >
        Not necessarily. ECMAScript implementations provide the bracket property
        accessor to use variable string values as property names, and the number of
        element properties that do not match the lowercase versions of their
        attribute name is limited.
        >
        See alsohttp://pointedears.de/scripts/dhtml.js:setAtt r()
        I'm interested in your mapping of char to ch, why is that? I noted an
        oddity with IE that getAttribute('c h') returns an empty string if the
        attribute isn't present when it should return null.

        Also you have:

        colSpan: "colSpan",

        should the property name have a lower case 's'?

        The DOM 2 Core specification says that getAttribute should return the
        value of an attribute as a string, however attributes such as
        disabled, checked, readonly, etc. don't have values specified in the
        HTML specification,
        >
        Yes, they have.
        >
        it just specifies a behaviour if the attribute is present or not.
        >
        Not true:
        >
        http://www.w3.org/TR/html401/intro/s...html#h-3.3.4.2
        Thanks, it would have been nice if a reference to that was included in
        appropriate places in the HTML 4 and DOM HTML specifications.

        The DOM HTML spec says that such attributes should
        return true or false, e.g. Inteface HTMLInputElemen t:
        >
        <URL:http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-50886781>
        >
        My interpretation is that if the attribute is accessed as a property
        of a DOM element (e.g. someElement.dis abled), it should return:
        >
        1. boolean true if the element has the attribute set in the markup
        or
        it has been set to true by script
        2. boolean false only if the attribute value has been set to false
        by script
        3. null if the attribute is not in the markup and hasn't been set by
        script,
        or if the element doesn't support the attribute
        >
        Correct.
        >
        That way the value of the DOM property can be easily converted to an
        equivalent string simply by using the returned object's toString
        method ('true', 'false' and '' respectively) which seems to fit the
        specification for getAttribute.
        >
        Yes, you could. However, this is what setAttribute() is for.
        >
        I don't know of a browser that behaves as described above, they all
        have foibles. If I were to write a generic getAttributeVal ue
        function, should it behave as described above,
        >
        It should not return boolean values as content of string values.
        It could return the object's toString value rather than the object.
        >
        or should it instead return 'disabled', '' and '' respectively? The
        logic could then be applied to other "no value" attributes such as
        checked, readonly and selected. Condition statements could be:
        >
        if (el.getAttribut eValue('disable d') == 'true') { ... }
        >
        which is reasonably consistent with:
        >
        if (el.disabled) { ... }
        >
        What do others think?
        >
        You should implement
        >
        if (_getAttributeV alue(el, 'disabled'))
        >
        if you don't like
        >
        if (el.getAttribut e('disabled').t oLowerCase() == 'disabled')
        >
        already. As you should know by now, host objects should not be tried
        to be augmented, and they cannot be prototyped universally.
        I wasn't suggesting augmenting host objects, I was just looking for a
        consistent way to get attribute values. The following function seems
        to do the trick, I haven't tested it widely yet. It has an issue with
        IE and attributes named 'ch', I await your response from the question
        above.


        function getAttributeVal ue(element, attribute)
        {
        var v, lowerAtt,
        htmlFlags = {
        checked: 'checked',
        compact: 'compact', // deprecated HTML 4
        declare: 'declare',
        defer: 'defer',
        disabled: 'disabled',
        ismap: 'ismap',
        multiple: 'multiple',
        nohref: 'nohref',
        noresize: 'noresize',
        noshade: 'noshade',
        nowrap: 'nowrap', // deprecated HTML 4
        readonly: 'readonly',
        selected: 'selected'
        },
        mapFwd = {
        alink: 'aLink',
        accesskey: 'accessKey',
        bgcolor: 'bgColor',
        cellpadding: 'cellPadding',
        cellspacing: 'cellSpacing',
        'char': 'ch',
        charoff: 'chOff',
        'class': 'className',
        codebase: 'codeBase',
        codetype: 'codeType',
        colspan: 'colSpan',
        datetime: 'dateTime',
        frameborder: 'frameBorder',
        'for': 'htmlFor',
        ismap: 'isMap',
        longdesc: 'longDesc',
        maxlength: 'maxLength',
        marginheight:'m arginHeight',
        marginwidth: 'marginWidth',
        nohref: 'noHref',
        noresize: 'noResize',
        noshade: 'noShade',
        nowrap: 'noWrap',
        readonly: 'readOnly',
        rowspan: 'rowSpan',
        tabindex: 'tabIndex',
        usemap: 'useMap',
        valuetype: 'valueType',
        vlink: 'vLink'
        },
        mapRev = {
        classname: 'class',
        // ch: 'char',
        htmlfor: 'for'
        };

        if (typeof attribute == 'string') {
        lowerAtt = attribute.toLow erCase();

        if (lowerAtt in htmlFlags) {
        return !!element[attribute]? htmlFlags[lowerAtt] : '';
        }

        v = element.getAttr ibute(attribute );

        if (v === null) {
        v = element.getAttr ibute(mapFwd[lowerAtt]);
        }

        if (v === null) {
        v = element.getAttr ibute(mapRev[lowerAtt]);
        }

        return v;
        }
        }


        --
        Rob

        Comment

        • Thomas 'PointedEars' Lahn

          #5
          Re: getAttribute question

          RobG wrote:
          [...] Thomas 'PointedEars' Lahn [...] wrote:
          >RobG wrote:
          >>I have always accessed attributes such as disabled using the DOM
          >>element property, however I was wondering about implementing a more
          >>generic function to get the values of attributes - which of course
          >>leads to the DOM Element Interface's getAttribute method:
          >><URL:http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-666EE0F9>
          >Not necessarily. ECMAScript implementations provide the bracket property
          >accessor to use variable string values as property names, and the number of
          >element properties that do not match the lowercase versions of their
          >attribute name is limited.
          >>
          >See alsohttp://pointedears.de/scripts/dhtml.js:setAtt r()
          (Eeek, Google Groups posting.)
          I'm interested in your mapping of char to ch, why is that?
          The `char' attribute of HTML 4.01 `COL', `COLGROUP', `TBODY', `TD', `TFOOT',
          `TH', `THEAD', and `TR' elements, and their lowercase XHTML 1.0 correlates,
          is represented by the `ch' attribute of the HTMLTableColEle ment,
          HTMLTableSectio nElement, HTMLTableCellEl ement, and HTMLTableRowEle ment
          interfaces of W3C DOM Level 2 HTML, and the `ch' property of the objects
          implementing these, respectively.



          I noted an oddity with IE that getAttribute('c h') returns an empty string if the
          attribute isn't present when it should return null.
          However, this is unsurprising, as it should have been getAttribute('c har').
          Also you have:
          >
          colSpan: "colSpan",
          >
          should the property name have a lower case 's'?
          Yes, it should. It had been fixed already in the local version (currently
          0.9.4.200804232 1), but thanks anyway.
          >>I don't know of a browser that behaves as described above, they all
          >>have foibles. If I were to write a generic getAttributeVal ue
          >>function, should it behave as described above,
          >It should not return boolean values as content of string values.
          >
          It could return the object's toString value rather than the object.
          Which object are you talking about? We are dealing with *primitive values*
          here. So if a method is to return the value of a boolean HTML attribute,
          there are two implementations I would consider reasonable: Either a) return
          the *boolean* values `true' or `false', or b) return the proper attribute
          values as strings, i.e. e.g. "disabled" if set and "" if not set. Either
          way, it should be easy to use the return value in a conditional expression,
          which both proposed implementations would accomplish.
          >>or should it instead return 'disabled', '' and '' respectively? The
          >>logic could then be applied to other "no value" attributes such as
          >>checked, readonly and selected. Condition statements could be:
          >> if (el.getAttribut eValue('disable d') == 'true') { ... }
          >>which is reasonably consistent with:
          >> if (el.disabled) { ... }
          >>What do others think?
          >You should implement
          >>
          > if (_getAttributeV alue(el, 'disabled'))
          >>
          >if you don't like
          >>
          > if (el.getAttribut e('disabled').t oLowerCase() == 'disabled')
          >>
          >already. As you should know by now, host objects should not be tried
          >to be augmented, and they cannot be prototyped universally.
          >
          I wasn't suggesting augmenting host objects, I was just looking for a
          consistent way to get attribute values.
          But el.getAttribute Value() is suggesting host object augmentation, is it not?
          [...]
          function getAttributeVal ue(element, attribute)
          {
          var v, lowerAtt,
          htmlFlags = {
          checked: 'checked',
          compact: 'compact', // deprecated HTML 4
          declare: 'declare',
          defer: 'defer',
          disabled: 'disabled',
          ismap: 'ismap',
          multiple: 'multiple',
          nohref: 'nohref',
          noresize: 'noresize',
          noshade: 'noshade',
          nowrap: 'nowrap', // deprecated HTML 4
          readonly: 'readonly',
          selected: 'selected'
          },
          There really is no need for `htmlFlags'.
          mapFwd = {
          [...]
          },
          ACK. This is also what I have.
          mapRev = {
          classname: 'class',
          // ch: 'char',
          htmlfor: 'for'
          };
          Why do you consider this necessary? Are we talking HTML attributes or not?
          if (typeof attribute == 'string') {
          This is not required, and unnecessarily limits the ways this method may be
          applied.
          lowerAtt = attribute.toLow erCase();
          I understand you test for the string type above because of this assignment,
          however any value can be converted to string easily:

          lowerAtt = String(attribut e).toLowerCase( );

          (attribute.toSt ring() is not always feasible.)
          if (lowerAtt in htmlFlags) {
          For reasons I mentioned before, the `in' operator should be avoided outside
          `for..in' statements for the time being.
          return !!element[attribute]? htmlFlags[lowerAtt] : '';
          While written more conveniently, the test accesses a property of a host
          object without testing for it first which is considered error-prone.
          }
          >
          v = element.getAttr ibute(attribute );
          Much the same here.
          if (v === null) {
          v = element.getAttr ibute(mapFwd[lowerAtt]);
          }
          >
          if (v === null) {
          v = element.getAttr ibute(mapRev[lowerAtt]);
          }
          Your assertions are not supported by the W3C DOM Level 2 and 3 Core
          Specifications. According to these, Element::getAtt ribute() never returns
          `null'. Faulty implementations do not justify your deliberately violating
          the standard yourself. So the least you have to consider instead is

          if (!v)
          {
          return v;
          }
          }

          Regards,

          PointedEars
          --
          realism: HTML 4.01 Strict
          evangelism: XHTML 1.0 Strict
          madness: XHTML 1.1 as application/xhtml+xml
          -- Bjoern Hoehrmann

          Comment

          Working...