Selección de attributes entre browseres en JavaScript sin formatting

Cuando no tengo acceso a JQuery por el motivo que sea, generalmente realizo la selección de attributes manualmente usando element.hasAttribute o element.getAttribute .

Sin embargo, parece que hay algunas complicaciones aquí porque los browseres más antiguos (IE <= 8) no admiten hasAttribute . Entonces, si desea verificar si un elemento tiene cierto atributo, debe usar getAttribute y verificar el valor de retorno.

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

Esto me hace pensar que también puedes olvidarte de utilizar hasAttribute y siempre usar getAttribute . El problema es que no puedo encontrar documentation consistente sobre el valor de retorno de getAttribute . En la práctica, devuelve null en la mayoría de los browseres si el atributo no existe, pero también puede devolver una cadena vacía , porque eso es lo que se supone que debe hacer según la especificación DOM 3.

Desafortunadamente, devolver una cadena vacía nos deja sin forma de desambiguar entre:

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

y

 <div></div> 

Entonces, en la práctica, parece que lo más portátil es verificar primero si el browser admite hasAttribute , y si no, usar getAttribute , ya que IE 6-8 implementa getAttribute para que devuelva null (en lugar de cadena vacía) si el atributo no existe.

¿Es esta la mejor manera de hacer esto? ¿O hay una mejor manera de escribir la detección de attributes entre browseres en Javascript simple?

Lo siguiente funciona bien en IE6-10 (probado en IETester), Firefox, Chrome y Safari:

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

Aquí están jsfiddle y su página de resultados independiente (para probar en browseres más antiguos).

Es probable que esto requiera algunas testings, pero ¿no cambiaría la longitud de la Cadena que describe el Elemento si usted intentó establecer un atributo que todavía no tiene, si sigue siendo el mismo si lo intentó para uno que sí lo tiene?

 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 }; }());