Obtenga todos los atributos de un elemento usando jQuery

127

Estoy tratando de pasar por un elemento y obtener todos los atributos de ese elemento para generarlos, por ejemplo, una etiqueta puede tener 3 o más atributos, desconocidos para mí y necesito obtener los nombres y valores de estos atributos. Estaba pensando en algo como:

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

¿Alguien podría decirme si esto es posible y, de ser así, cuál sería la sintaxis correcta?

Styphon
fuente

Respuestas:

246

La attributespropiedad los contiene a todos:

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

Lo que también puede hacer es extender .attrpara que pueda llamarlo como .attr()para obtener un objeto simple de todos los 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 data-a='1' id='b'>");
$div.attr();  // { "data-a": "1", "id": "b" }
pimvdb
fuente
1
Es posible que desee solucionarlo cuando no haya elementos coincidentes, por ejemplo$().attr()
Alexander
11
La attributescolección contiene todos los atributos posibles en IE anteriores, no solo los que se han especificado en el HTML. Puede solucionar esto filtrando la lista de atributos utilizando cada specifiedpropiedad de atributos .
Tim Down
77
Esta es una funcionalidad muy buena y esperada para el .attr()método jQuery . Es extraño que jQuery no lo incluya.
ivkremer
sólo un poco de curiosidad para saber que por qué estamos accediendo a ella como una matriz en this[0].attributes?
Vishal
attributesSin embargo, no es una matriz ... en Chrome, al menos, es un NamedNodeMap, que es un objeto.
Samuel Edwin Ward
26

Aquí hay una descripción general de las muchas formas en que se puede hacer, para mi propia referencia y la tuya :) Las funciones devuelven un hash de nombres de atributos y sus valores.

Vanilla 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;
}

Vanilla JS con Array.reduce

Funciona para navegadores compatibles con ES 5.1 (2011). Requiere IE9 +, no funciona en 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

Esta función espera un objeto jQuery, no un elemento DOM.

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

    return attrs;
}

Guion bajo

También funciona para lodash.

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

lodash

Es aún más conciso que la versión Underscore, pero solo funciona para lodash, no para Underscore. Requiere IE9 +, tiene errores en IE8. Felicitaciones a @AlJey por eso .

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

Página de prueba

En JS Bin, hay una página de prueba en vivo que cubre todas estas funciones. La prueba incluye atributos booleanos ( hidden) y atributos enumerados ( contenteditable="").

hashchange
fuente
3

Un script de depuración (solución jquery basada en la respuesta anterior 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
zzapper
fuente
2

con LoDash simplemente podrías hacer esto:

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

Usando la función javascript es más fácil obtener todos los atributos de un elemento en NamedArrayFormat.

$("#myTestDiv").click(function(){
  var attrs = document.getElementById("myTestDiv").attributes;
  $.each(attrs,function(i,elem){
    $("#attrs").html(    $("#attrs").html()+"<br><b>"+elem.name+"</b>:<i>"+elem.value+"</i>");
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="myTestDiv" ekind="div" etype="text" name="stack">
click This
</div>
<div id="attrs">Attributes are <div>

Vishnu Prasanth G
fuente
0

Solución simple por Underscore.js

Por ejemplo: Obtenga todos los enlaces de texto de los padres de los alumnos que tienen clase someClass

_.pluck($('.someClass').find('a'), 'text');

Violín de trabajo

pymen
fuente
0

Mi sugerencia:

$.fn.attrs = function (fnc) {
    var obj = {};
    $.each(this[0].attributes, function() {
        if(this.name == 'value') return; // Avoid someone (optional)
        if(this.specified) obj[this.name] = this.value;
    });
    return obj;
}

var a = $ (el) .attrs ();

Guillermo
fuente