setAttribute(): make 2nd parameter optional for boolean attributes


#1

The second parameter of the Element.setAttribute() (JS/DOM) is redundant when setting a boolean attribute. So it would probably make sense to make it optional, so that the following calls are equivalent:

example.setAttribute('data-mybool', '');
example.setAttribute('data-mybool');

If the boolean attribute to set already exists, the method should probably do nothing.

A proof-of-concept polyfill:

(function() {
    var nativeFunction = Element.prototype.setAttribute;

    Element.prototype.setAttribute = function(name, value) {
        if ('undefined' === typeof value) {
            if (this.hasAttribute(name)) {
                return;
            }

            this.setAttribute(name, '');
        }
        else {
            nativeFunction.call(this, name, value);
        }
    };
})();

#2

“Boolean” attributes are purely a parsing convenience; as far as the DOM is concerned, there’s no such thing - all attributes have values. It seems worthwhile to keep that fact explicit, so people aren’t surprised when they see that an attribute has a value of "".


#3

Standard boolean attributes (disabled, required, etc.) are directly mapped to properties that are boolean (true / false) by definition, so this is not just about parsing.

so people aren’t surprised when they see that an attribute has a value of “”.

What exact negative impact you think could be a result of some people being surprised?


#4

But if it’s a standard boolean attribute, it has an interface on the relevant element prototype, right?

let p = document.query('p');
// short & sweet
p.hidden = true;
// longer & backwards-compatible
p.setAttribute('hidden', '');
// proposed here, and not backwards-compatible
p.setAttribute('hidden');

#5

The fact that standard boolean attributes are directly mapped to boolean properties just proves that boolean attributes are not just about parsing as Tab has stated.

This in no way means that custom attributes like data-foo cannot be used as boolean, but setting a property like dataFoo to true does not set the corresponding data-foo attribute to '' value, as well as setting the property to false does not remove the attribute.

Backward compatibility is an ephemeral thing in general (moreso in a discussion of any new feature by nature), but anyway, the proposed feature can be polyfilled easily and seamlessly as I’ve shown in my starting message.