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?

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" }

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="").


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

2

avec LoDash, vous pouvez simplement faire ceci:

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

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>


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


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.