9

When I don't have access to JQuery for whatever reason, I usually perform attribute selection manually using element.hasAttribute or element.getAttribute.

However, there seems to be some complication here because older browsers (IE <= 8) don't support hasAttribute. So if you want to check whether an element has a certain attribute, you need to use getAttribute and check the return value.

if ((element.hasAttribute && element.hasAttribute("foo"))
    || (element.getAttribute("foo") != null))
{
  ....
}

This makes me think you may as well just forget about using hasAttribute at all, and just always use getAttribute. The problem is that I can't find consistent documentation on the return value of getAttribute. In practice, it returns null on most browsers if the attribute doesn't exist - but it also might return empty string, because that is what it's supposed to do according to the DOM 3 specification.

Unfortunately, returning an empty string leaves us with no way to disambiguate between:

<div data-my-attribute = ""></div>

and

<div></div>

So, in practice - it seems the most portable thing to do is to first check if the browser supports hasAttribute, and if not, use getAttribute - since IE 6-8 implement getAttribute so that it returns null (instead of empty string) if the attribute doesn't exist.

Is this really the best way to go about doing this? Or is there a better way to write cross-browser attribute detection in plain Javascript?

7
  • 12
    Welcome to the main reason jQuery exists. Browser normalization isn't easy. Commented Jun 14, 2013 at 16:43
  • Look at some framework source code to get ideas. Commented Jun 14, 2013 at 16:44
  • 2
    Could you provide a use case where you'd really need to disambiguate between <div foo=""> and <div>? Commented Jun 14, 2013 at 16:49
  • 1
    @thg435 according to the spec, the former is truthy, and the latter is falsy Commented Jun 14, 2013 at 16:54
  • 3
    I'm just thinking out lout, but maybe <input ... required> is such a case. Commented Jun 14, 2013 at 16:56

2 Answers 2

1

The following works well in IE6-10 (tested it in IETester), Firefox, Chrome and Safari:

function hasAttrib(element, attributeName) {
  return (typeof element.attributes[attributeName] != 'undefined');
}

Here are jsfiddle and its standalone result page (for testing in older browsers).

Sign up to request clarification or add additional context in comments.

Comments

0

This will probably need some testing, but would not the length of the String describing the Element change if you tried to setAttribute an attribute it doesn't already have vs remain the same if you tried for one it does have?

var hasAttribute = (function () {
    if (HTMLElement && HTMLElement.prototype
                    && HTMLElement.prototype.hasAttribute)
        return function (node, attrib) { // use if available
            return node.hasAttribute(attrib);
        };
    return function (node, attrib) {
        var d = document.createElement('div'), // node for innerHTML
            e = node.cloneNode(false), // id attribute will be lost here
            i;
        if (attrib.toLowerCase() === 'id') return !!node.getAttribute('id');
        d.appendChild(e);
        i = d.innerHTML.length;                         // get original length
        e.setAttribute(attrib, e.getAttribute(attrib)); // set attrib to test
        return d.innerHTML.length === i;                // see if length changed
    };
}());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.