Obtenir tous les attributs d'un élément HTML avec Javascript / jQuery


161

Je veux mettre tous les attributs d'un élément Html dans un tableau: comme si j'avais un objet jQuery, qui ressemble à html:

<span name="test" message="test2"></span>

maintenant, une façon est d'utiliser l'analyseur xml décrit ici , mais ensuite j'ai besoin de savoir comment obtenir le code html de mon objet.

l'autre façon est de le faire avec jquery, mais comment? le nombre d'attributs et les noms sont génériques.

Merci

Btw: Je ne peux pas accéder à l'élément avec document.getelementbyid ou quelque chose de similaire.

Réponses:


218

Si vous voulez juste les attributs DOM, il est probablement plus simple d'utiliser la attributesliste de nœuds sur l'élément lui-même:

var el = document.getElementById("someId");
for (var i = 0, atts = el.attributes, n = atts.length, arr = []; i < n; i++){
    arr.push(atts[i].nodeName);
}

Notez que cela remplit le tableau uniquement avec des noms d'attributs. Si vous avez besoin de la valeur d'attribut, vous pouvez utiliser la nodeValuepropriété:

var nodes=[], values=[];
for (var att, i = 0, atts = el.attributes, n = atts.length; i < n; i++){
    att = atts[i];
    nodes.push(att.nodeName);
    values.push(att.nodeValue);
}

Le problème est que je ne peux pas utiliser getElementById, c'est un objet jquery. y a-t-il un moyen de créer getelementbyclassname dans un contexte comme jquery?
k0ni

4
Vous pouvez utiliser getElementById-var el = document.getElementById($(myObj).attr("id"));
Sampson

45
Vous pouvez obtenir l'objet DOM à partir d'un objet jQuery via la getméthode ... ex:var obj = $('#example').get(0);
Matt Huggins

3
@ k0ni - pourriez-vous utiliser par exemple var atts = $ (monObjet) [0] .attributes; ?
Ralph Cowling

12
Attention: dans IE, cela n'est pas seulement spécifié, mais tous les attributs possibles
Alexey Lebedev

70

Vous pouvez utiliser ce simple plugin comme $ ('# some_id'). GetAttributes ();

(function($) {
    $.fn.getAttributes = function() {
        var attributes = {}; 

        if( this.length ) {
            $.each( this[0].attributes, function( index, attr ) {
                attributes[ attr.name ] = attr.value;
            } ); 
        }

        return attributes;
    };
})(jQuery);

4
FYI: Cela expose uniquement le premier élément du sélecteur.
Brett Veenstra

J'ai testé et cela fonctionne avec des attributs ajoutés dynamiquement (chrome)
CodeToad

57

Facile:

var element = $("span[name='test']");
$(element[0].attributes).each(function() {
console.log(this.nodeName+':'+this.nodeValue);});

Y a-t-il des inconvénients à cela?
rzr

7
Attr.nodeValueest obsolète en faveur de value, dit Google Chrome. Donc ça pourrait être this.name + ':' + this.value. The Attr Interface
Thai

20

Parce que dans IE7 elem.attributes répertorie tous les attributs possibles, pas seulement les présents, nous devons tester la valeur de l'attribut. Ce plugin fonctionne dans tous les principaux navigateurs:

(function($) {
    $.fn.getAttributes = function () {
        var elem = this, 
            attr = {};

        if(elem && elem.length) $.each(elem.get(0).attributes, function(v,n) { 
            n = n.nodeName||n.name;
            v = elem.attr(n); // relay on $.fn.attr, it makes some filtering and checks
            if(v != undefined && v !== false) attr[n] = v
        })

        return attr
    }
})(jQuery);

Usage:

var attribs = $('#some_id').getAttributes();

1
Une faute de frappe dans ce - el.get (0) à la ligne 6 devrait être elem.get (0).
Graham Charles

D'après mon expérience à l'instant, c'est en fait un peu plus complexe que cela. Au moins dans certains cas. Par exemple, cela inclura-t-il un attribut nommé 'dataFld' avec la valeur 'null' (valeur de chaîne) ou l'exclurait-il?
mightyiam

Cela ne fonctionne pas avec les propriétés ajoutées dynamiquement, car les propriétés et les attributs ne sont pas toujours synchronisés.
DUzun

18

Setter et Getter!

(function($) {
    // Attrs
    $.fn.attrs = function(attrs) {
        var t = $(this);
        if (attrs) {
            // Set attributes
            t.each(function(i, e) {
                var j = $(e);
                for (var attr in attrs) {
                    j.attr(attr, attrs[attr]);
                }
            });
            return t;
        } else {
            // Get attributes
            var a = {},
                r = t.get(0);
            if (r) {
                r = r.attributes;
                for (var i in r) {
                    var p = r[i];
                    if (typeof p.nodeValue !== 'undefined') a[p.nodeName] = p.nodeValue;
                }
            }
            return a;
        }
    };
})(jQuery);

Utilisation:

// Setter
$('#element').attrs({
    'name' : 'newName',
    'id' : 'newId',
    'readonly': true
});

// Getter
var attrs = $('#element').attrs();

2
Bien, j'aime bien cette réponse. S'intègre parfaitement bien avec jQuery.attr.
Scott Rippey

1
Deux recommandations: pouvez-vous mettre à jour pour utiliser des noms de variables «non minifiés»? Et je vois que vous utilisez jQuery.attrdans le setter, mais il serait probablement avantageux de l'utiliser aussi dans le getter.
Scott Rippey

Aussi, petite chose - il ne devrait pas y avoir de point-virgule après votre première instruction for ().
jbyrd

6

Utiliser .slicepour convertir la attributespropriété en tableau

La attributespropriété des nœuds DOM est a NamedNodeMap, qui est un objet de type Array.

Un objet de type Array est un objet qui a une lengthpropriété et dont les noms de propriété sont énumérés, mais qui a ses propres méthodes et n'hérite pas deArray.prototype

La sliceméthode peut être utilisée pour convertir des objets de type Array en un nouveau Array .

var elem  = document.querySelector('[name=test]'),
    attrs = Array.prototype.slice.call(elem.attributes);

console.log(attrs);
<span name="test" message="test2">See console.</span>


1
Il renverra un tableau d'objets et non de noms d'attributs sous forme de chaînes, cependant
Przemek

1
L'OP n'a pas spécifié de tableau de noms sous forme de chaînes: "Je veux mettre tous les attributs d'un élément Html dans un tableau." Cela fait cela.
gfullam

OK, c'est logique
Przemek

1
Lors de l'itération sur les éléments dans attrs, vous pouvez accéder au nom de l'attribut avec la namepropriété de l'élément.
tyler.frankenstein

3

Cette approche fonctionne bien si vous devez obtenir tous les attributs avec le nom et la valeur dans les objets renvoyés dans un tableau.

Exemple de sortie:

[
    {
        name: 'message',
        value: 'test2'
    }
    ...
]

function getElementAttrs(el) {
  return [].slice.call(el.attributes).map((attr) => {
    return {
      name: attr.name,
      value: attr.value
    }
  });
}

var allAttrs = getElementAttrs(document.querySelector('span'));
console.log(allAttrs);
<span name="test" message="test2"></span>

Si vous ne voulez qu'un tableau de noms d'attributs pour cet élément, vous pouvez simplement mapper les résultats:

var onlyAttrNames = allAttrs.map(attr => attr.name);
console.log(onlyAttrNames); // ["name", "message"]

2

La réponse de Roland Bouman est la meilleure façon simple de Vanilla. J'ai remarqué quelques tentatives de plugs jQ, mais elles ne me paraissaient pas assez "pleines", alors j'ai fait les miennes. Le seul revers jusqu'à présent a été l'incapacité d'accéder à des attrs ajoutés dynamiquement sans appeler directement elm.attr('dynamicAttr'). Cependant, cela retournera tous les attributs naturels d'un objet élément jQuery.

Le plugin utilise un simple appel de style jQuery:

$(elm).getAttrs();
// OR
$.getAttrs(elm);

Vous pouvez également ajouter un deuxième paramètre de chaîne pour obtenir un seul attr spécifique. Ce n'est pas vraiment nécessaire pour la sélection d'un élément, car jQuery le fournit déjà $(elm).attr('name'), cependant, ma version d'un plugin permet plusieurs retours. Ainsi, par exemple, un appel comme

$.getAttrs('*', 'class');

Se traduira par un []retour de tableau d'objets {}. Chaque objet ressemblera à:

{ class: 'classes names', elm: $(elm), index: i } // index is $(elm).index()

Brancher

;;(function($) {
    $.getAttrs || ($.extend({
        getAttrs: function() {
            var a = arguments,
                d, b;
            if (a.length)
                for (x in a) switch (typeof a[x]) {
                    case "object":
                        a[x] instanceof jQuery && (b = a[x]);
                        break;
                    case "string":
                        b ? d || (d = a[x]) : b = $(a[x])
                }
            if (b instanceof jQuery) {
                var e = [];
                if (1 == b.length) {
                    for (var f = 0, g = b[0].attributes, h = g.length; f < h; f++) a = g[f], e[a.name] = a.value;
                    b.data("attrList", e);
                    d && "all" != d && (e = b.attr(d))
                } else d && "all" != d ? b.each(function(a) {
                    a = {
                        elm: $(this),
                        index: $(this).index()
                    };
                    a[d] = $(this).attr(d);
                    e.push(a)
                }) : b.each(function(a) {
                    $elmRet = [];
                    for (var b = 0, d = this.attributes, f = d.length; b < f; b++) a = d[b], $elmRet[a.name] = a.value;
                    e.push({
                        elm: $(this),
                        index: $(this).index(),
                        attrs: $elmRet
                    });
                    $(this).data("attrList", e)
                });
                return e
            }
            return "Error: Cannot find Selector"
        }
    }), $.fn.extend({
        getAttrs: function() {
            var a = [$(this)];
            if (arguments.length)
                for (x in arguments) a.push(arguments[x]);
            return $.getAttrs.apply($, a)
        }
    }))
})(jQuery);

Conforme

;;(function(c){c.getAttrs||(c.extend({getAttrs:function(){var a=arguments,d,b;if(a.length)for(x in a)switch(typeof a[x]){case "object":a[x]instanceof jQuery&&(b=a[x]);break;case "string":b?d||(d=a[x]):b=c(a[x])}if(b instanceof jQuery){if(1==b.length){for(var e=[],f=0,g=b[0].attributes,h=g.length;f<h;f++)a=g[f],e[a.name]=a.value;b.data("attrList",e);d&&"all"!=d&&(e=b.attr(d));for(x in e)e.length++}else e=[],d&&"all"!=d?b.each(function(a){a={elm:c(this),index:c(this).index()};a[d]=c(this).attr(d);e.push(a)}):b.each(function(a){$elmRet=[];for(var b=0,d=this.attributes,f=d.length;b<f;b++)a=d[b],$elmRet[a.name]=a.value;e.push({elm:c(this),index:c(this).index(),attrs:$elmRet});c(this).data("attrList",e);for(x in $elmRet)$elmRet.length++});return e}return"Error: Cannot find Selector"}}),c.fn.extend({getAttrs:function(){var a=[c(this)];if(arguments.length)for(x in arguments)a.push(arguments[x]);return c.getAttrs.apply(c,a)}}))})(jQuery);

jsFiddle


2

Des moyens beaucoup plus concis de le faire:

Ancienne méthode (IE9 +):

var element = document.querySelector(/* … */);
[].slice.call(element.attributes).map(function (attr) { return attr.nodeName; });

Voie ES6 (Edge 12+):

[...document.querySelector(/* … */).attributes].map(attr => attr.nodeName);
  • document.querySelector()renvoie le premier élément du document qui correspond au sélecteur spécifié.
  • Element.attributesrenvoie un objet NamedNodeMap contenant les attributs attribués de l'élément HTML correspondant.
  • [].map() crée un nouveau tableau avec les résultats de l'appel d'une fonction fournie sur chaque élément du tableau appelant.

Démo:


1

est-ce que cela aide?

Cette propriété renvoie tous les attributs d'un élément dans un tableau pour vous. Voici un exemple.

window.addEventListener('load', function() {
  var result = document.getElementById('result');
  var spanAttributes = document.getElementsByTagName('span')[0].attributes;
  for (var i = 0; i != spanAttributes.length; i++) {
    result.innerHTML += spanAttributes[i].value + ',';
  }
});
<span name="test" message="test2"></span>
<div id="result"></div>

Pour obtenir les attributs de nombreux éléments et les organiser, je suggère de créer un tableau de tous les éléments que vous souhaitez parcourir, puis de créer un sous-tableau pour tous les attributs de chaque élément en boucle.

Voici un exemple de script qui parcourra les éléments collectés et affichera deux attributs. Ce script suppose qu'il y aura toujours deux attributs, mais vous pouvez facilement résoudre ce problème avec un mappage supplémentaire.

window.addEventListener('load',function(){
  /*
  collect all the elements you want the attributes
  for into the variable "elementsToTrack"
  */ 
  var elementsToTrack = $('body span, body div');
  //variable to store all attributes for each element
  var attributes = [];
  //gather all attributes of selected elements
  for(var i = 0; i != elementsToTrack.length; i++){
    var currentAttr = elementsToTrack[i].attributes;
    attributes.push(currentAttr);
  }
  
  //print out all the attrbute names and values
  var result = document.getElementById('result');
  for(var i = 0; i != attributes.length; i++){
    result.innerHTML += attributes[i][0].name + ', ' + attributes[i][0].value + ' | ' + attributes[i][1].name + ', ' + attributes[i][1].value +'<br>';  
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span name="test" message="test2"></span>
<span name="test" message="test2"></span>
<span name="test" message="test2"></span>
<span name="test" message="test2"></span>
<span name="test" message="test2"></span>
<span name="test" message="test2"></span>
<span name="test" message="test2"></span>
<div name="test" message="test2"></div>
<div name="test" message="test2"></div>
<div name="test" message="test2"></div>
<div name="test" message="test2"></div>
<div id="result"></div>


1

Chaque réponse ici manque la solution la plus simple utilisant la méthode d'élément getAttributeNames !

Il récupère les noms de tous les attributs courants de l'élément sous la forme d'un tableau normal, que vous pouvez ensuite réduire en un bel objet de clés / valeurs.

const getAllAttributes = el => el
  .getAttributeNames()
  .reduce((obj, name) => ({
    ...obj,
    [name]: el.getAttribute(name)
  }), {})

console.log(getAllAttributes(document.querySelector('div')))
<div title="hello" className="foo" data-foo="bar"></div>


1

Imaginez que vous avez un élément HTML comme ci-dessous:

<a class="toc-item"
   href="/books/n/ukhta2333/s5/"
   id="book-link-29"
>
   Chapter 5. Conclusions and recommendations
</a>

Une façon d'en obtenir tous les attributs est de les convertir en un tableau:

const el = document.getElementById("book-link-29")
const attrArray = Array.from(el.attributes)

// Now you can iterate all the attributes and do whatever you need.
const attributes = attrArray.reduce((attrs, attr) => {
    attrs !== '' && (attrs += ' ')
    attrs += `${attr.nodeName}="${attr.nodeValue}"`
    return attrs
}, '')
console.log(attributes)

Et ci-dessous se trouve la chaîne que vous obtiendrez (de l'exemple), qui comprend tous les attributs:

class="toc-item" href="/books/n/ukhta2333/s5/" id="book-link-29"

0

Essayez quelque chose comme ça

    <div id=foo [href]="url" class (click)="alert('hello')" data-hello=world></div>

puis récupérez tous les attributs

    const foo = document.getElementById('foo');
    // or if you have a jQuery object
    // const foo = $('#foo')[0];

    function getAttributes(el) {
        const attrObj = {};
        if(!el.hasAttributes()) return attrObj;
        for (const attr of el.attributes)
            attrObj[attr.name] = attr.value;
        return attrObj
    }

    // {"id":"foo","[href]":"url","class":"","(click)":"alert('hello')","data-hello":"world"}
    console.log(getAttributes(foo));

pour un tableau d'attributs, utilisez

    // ["id","[href]","class","(click)","data-hello"]
    Object.keys(getAttributes(foo))

0
Element.prototype.getA = function (a) {
        if (a) {
            return this.getAttribute(a);
        } else {
            var o = {};
            for(let a of this.attributes){
                o[a.name]=a.value;
            }
            return o;
        }
    }

avoir <div id="mydiv" a='1' b='2'>...</div> peut utiliser

mydiv.getA() // {id:"mydiv",a:'1',b:'2'}

0

Très simple. Il vous suffit de faire une boucle sur l'élément attributes et de pousser leurs nodeValues ​​dans un tableau:

let att = document.getElementById('id');

let arr = Array();

for (let i = 0; i < att.attributes.length; i++) {
    arr.push(att.attributes[i].nodeValue);
}

Si vous voulez le nom de l'attribut, vous pouvez remplacer «nodeValue» par «nodeName».

let att = document.getElementById('id');

let arr = Array();

for (let i = 0; i < att.attributes.length; i++) {
    arr.push(att.attributes[i].nodeName);
}

0

Conversion d'attributs en objet

* Nécessite: lodash

function getAttributes(element, parseJson=false){
    let results = {}
    for (let i = 0, n = element.attributes.length; i < n; i++){
        let key = element.attributes[i].nodeName.replace('-', '.')
        let value = element.attributes[i].nodeValue
        if(parseJson){
            try{
                if(_.isString(value))
                value = JSON.parse(value)
            } catch(e) {}
        }
        _.set(results, key, value)
    }
    return results
}

Cela convertira tous les attributs html en un objet imbriqué

Exemple HTML: <div custom-nested-path1="value1" custom-nested-path2="value2"></div>

Résultat: {custom:{nested:{path1:"value1",path2:"value2"}}}

Si parseJson est défini sur true, les valeurs json seront converties en objets


-8

En javascript:

var attributes;
var spans = document.getElementsByTagName("span");
for(var s in spans){
  if (spans[s].getAttribute('name') === 'test') {
     attributes = spans[s].attributes;
     break;
  }
}

Pour accéder aux noms et valeurs des attributs:

attributes[0].nodeName
attributes[0].nodeValue

Traverser tous les éléments de portée serait trop lent
0-0
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.