Obtenez tous les attributs d'un élément à l'aide de jQuery

127

J'essaie de parcourir un élément et d'obtenir tous les attributs de cet élément pour les afficher, par exemple une balise peut avoir 3 attributs ou plus, inconnus de moi et j'ai besoin d'obtenir les noms et les valeurs de ces attributs. Je pensais à quelque chose du genre:

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

Quelqu'un pourrait-il me dire si cela est même possible et, dans l'affirmative, quelle serait la syntaxe correcte?

Styphon
la source

Réponses:

246

La attributespropriété les contient tous:

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

Ce que vous pouvez également faire est de l'étendre .attrafin que vous puissiez l'appeler comme .attr()pour obtenir un objet simple de tous les attributs:

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

Usage:

var $div = $("<div data-a='1' id='b'>");
$div.attr();  // { "data-a": "1", "id": "b" }
pimvdb
la source
1
Vous voudrez peut-être le réparer lorsqu'il n'y a pas d'éléments correspondants, par exemple$().attr()
Alexander
11
La attributescollection contient tous les attributs possibles dans l'ancien IE, pas seulement ceux qui ont été spécifiés dans le HTML. Vous pouvez contourner ce problème en filtrant la liste des attributs à l'aide de chaque specifiedpropriété d' attributs .
Tim Down
7
C'est une fonctionnalité très bonne et attendue pour la .attr()méthode jQuery . C'est étrange que jQuery ne l'inclut pas.
ivkremer
juste un peu curieux de savoir pourquoi nous y accédons en tant que tableau this[0].attributes?
Vishal
attributesn'est pas un tableau cependant ... dans Chrome au moins c'est un NamedNodeMap, qui est un objet.
Samuel Edwin Ward
26

Voici un aperçu des nombreuses façons qui peuvent être faites, pour ma propre référence ainsi que la vôtre :) Les fonctions renvoient un hachage des noms d'attributs et de leurs valeurs.

Vanille 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 avec Array.reduce

Fonctionne pour les navigateurs prenant en charge ES 5.1 (2011). Nécessite IE9 +, ne fonctionne pas dans 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

Cette fonction attend un objet jQuery, pas un élément DOM.

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

    return attrs;
}

Souligner

Fonctionne également pour le lodash.

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

lodash

Est encore plus concis que la version Underscore, mais ne fonctionne que pour lodash, pas pour Underscore. Nécessite IE9 +, est bogué dans IE8. Félicitations à @AlJey pour celui-là .

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

Page de test

Chez JS Bin, il existe une page de test en direct couvrant toutes ces fonctions. Le test comprend des attributs booléens ( hidden) et des attributs énumérés ( contenteditable="").

changement de hachage
la source
3

Un script de débogage (solution jquery basée sur la réponse ci-dessus par 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
la source
2

avec LoDash, vous pouvez simplement faire ceci:

_.transform(this.attributes, function (result, item) {
  item.specified && (result[item.name] = item.value);
}, {});
Eugène Kuzmenko
la source
0

En utilisant la fonction javascript, il est plus facile d'obtenir tous les attributs d'un élément dans 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
la source
0

Solution simple par Underscore.js

Par exemple: obtenez le texte de tous les liens dont les parents ont la classe someClass

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

Violon de travail

pymen
la source
0

Ma suggestion:

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

William
la source