Obter todos os atributos de um elemento usando jQuery

Eu estou tentando passar por um elemento e obter todos os atributos desse elemento para produzi-los, por exemplo, uma tag pode ter 3 ou mais atributos, desconhecidos para mim e eu preciso obter os nomes e valores desses atributos. Eu estava pensando em algo ao longo das linhas:

$(this).attr().each(function(index, element) { var name = $(this).name; var value = $(this).value; //Do something with name and value... }); 

Alguém poderia me dizer se isso é possível e, em caso afirmativo, qual seria a syntax correta?

A propriedade de attributes contém todos eles:

 $(this).each(function() { $.each(this.attributes, function() { // this.attributes is not a plain object, but an array // of attribute nodes, which contain both the name and value if(this.specified) { console.log(this.name, this.value); } }); }); 

O que você também pode fazer é extender .attr para poder chamá-lo como .attr() para obter um object simples de todos os atributos:

 (function(old) { $.fn.attr = function() { if(arguments.length === 0) { if(this.length === 0) { return null; } var obj = {}; $.each(this[0].attributes, function() { if(this.specified) { obj[this.name] = this.value; } }); return obj; } return old.apply(this, arguments); }; })($.fn.attr); 

Uso:

 var $div = $("
"); $div.attr(); // { "data-a": "1", "id": "b" }

Aqui está uma visão geral das muitas maneiras que podem ser feitas, para minha própria referência, bem como a sua 🙂 As funções retornam um hash de nomes de atributos e seus valores.

Baunilha JS :

 function getAttributes ( node ) { var i, attributeNodes = node.attributes, length = attributeNodes.length, attrs = {}; for ( i = 0; i < length; i++ ) attrs[attributeNodes[i].name] = attributeNodes[i].value; return attrs; } 

Baunilha JS com Array.reduce

Funciona para navegadores que suportam ES 5.1 (2011). Requer IE9 +, não funciona no IE8.

 function getAttributes ( node ) { var attributeNodeArray = Array.prototype.slice.call( node.attributes ); return attributeNodeArray.reduce( function ( attrs, attribute ) { attrs[attribute.name] = attribute.value; return attrs; }, {} ); } 

jQuery

Essa function espera um object jQuery, não um elemento DOM.

 function getAttributes ( $node ) { var attrs = {}; $.each( $node[0].attributes, function ( index, attribute ) { attrs[attribute.name] = attribute.value; } ); return attrs; } 

Sublinhado

Também funciona para lodash.

 function getAttributes ( node ) { return _.reduce( node.attributes, function ( attrs, attribute ) { attrs[attribute.name] = attribute.value; return attrs; }, {} ); } 

lodash

É ainda mais conciso do que a versão Underscore, mas funciona apenas para o lodash, não para o Underscore. Requer o IE9 +, tem bugs no IE8. Parabéns ao @AlJey por esse .

 function getAttributes ( node ) { return _.transform( node.attributes, function ( attrs, attribute ) { attrs[attribute.name] = attribute.value; }, {} ); } 

Página de teste

No JS Bin, há uma página de teste ao vivo cobrindo todas essas funções. O teste inclui atributos booleanos ( hidden ) e atributos enumerados ( contenteditable="" ).

com o LoDash você poderia simplesmente fazer isso:

 _.transform(this.attributes, function (result, item) { item.specified && (result[item.name] = item.value); }, {}); 

Usando a function javascript, é mais fácil obter todos os atributos de um elemento no NamedArrayFormat.

 $("#myTestDiv").click(function(){ var attrs = document.getElementById("myTestDiv").attributes; $.each(attrs,function(i,elem){ $("#attrs").html( $("#attrs").html()+"
"+elem.name+":"+elem.value+""); }); });
  
click This
Attributes are

Um script de debugging (solução jquery baseada na resposta acima por hashchange)

 function getAttributes ( $node ) { $.each( $node[0].attributes, function ( index, attribute ) { console.log(attribute.name+':'+attribute.value); } ); } getAttributes($(this)); // find out what attributes are available