Ottieni tutti gli attributi da un elemento HTML con Javascript / jQuery


161

Voglio mettere tutti gli attributi in un elemento HTML in un array: come se avessi un oggetto jQuery, il cui html è simile al seguente:

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

ora un modo è quello di utilizzare il parser XML qui descritto , ma poi devo sapere come ottenere il codice HTML del mio oggetto.

l'altro modo è farlo con jquery, ma come? il numero di attributi e i nomi sono generici.

Grazie

A proposito: non riesco ad accedere all'elemento con document.getelementbyid o qualcosa di simile.

Risposte:


218

Se desideri solo gli attributi DOM, è probabilmente più semplice utilizzare l' attributeselenco dei nodi sull'elemento stesso:

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

Si noti che questo riempie l'array solo con i nomi degli attributi. Se è necessario il valore dell'attributo, è possibile utilizzare la nodeValueproprietà:

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

Il problema è che non riesco a usare getElementById, è un oggetto jquery. c'è un modo in cui posso fare getelementbyclassname all'interno di un contesto come su jquery?
k0ni,

4
Puoi usare getElementById-var el = document.getElementById($(myObj).attr("id"));
Sampson il

45
È possibile ottenere l'oggetto DOM da un oggetto jQuery tramite il getmetodo ... ad esempio:var obj = $('#example').get(0);
Matt Huggins

3
@ k0ni - potresti usare ad esempio var atts = $ (myObject) [0] .attributes; ?
Ralph Cowling,

12
Avvertenza: in IE questo non viene solo specificato, ma tutti i possibili attributi
Alexey Lebedev

70

Puoi usare questo semplice plugin come $ ('# 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: Questo espone solo il primo elemento del selettore.
Brett Veenstra,

Ho testato e funziona con attributi aggiunti dinamicamente (chrome)
CodeToad

57

Semplice:

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

Qualche svantaggio di questo?
rzr

7
Attr.nodeValueè deprecato a favore di value, afferma Google Chrome. Quindi potrebbe essere this.name + ':' + this.value. L'interfaccia Attr
Thai,

20

Perché in IE7 elem.attributes elenca tutti i possibili attributi, non solo quelli attuali, dobbiamo testare il valore dell'attributo. Questo plugin funziona in tutti i principali browser:

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

Uso:

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

1
Digitare in questo - el.get (0) alla riga 6 dovrebbe essere elem.get (0).
Graham Charles,

Dalla mia esperienza in questo momento questo è in realtà un po 'più complesso di così. Almeno in alcuni casi. Ad esempio, includerà un attributo chiamato 'dataFld' con valore 'null' (valore stringa) o lo escluderebbe?
mightyiam,

Non funziona con le proprietà aggiunte dinamicamente, poiché le proprietà e gli attributi non sono sempre sincronizzati.
DUzun,

18

Setter e 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);

Uso:

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

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

2
Bene, mi piace questa risposta al meglio. Si adatta perfettamente a jQuery.attr.
Scott Rippey,

1
Due consigli: puoi aggiornare per usare nomi di variabili "non minimizzati"? E vedo che stai usando jQuery.attrnel setter, ma probabilmente sarebbe utile usarlo anche nel getter.
Scott Rippey,

Inoltre, piccola cosa: non ci dovrebbe essere un punto e virgola dopo la prima istruzione for ().
jbyrd,

6

Utilizzare .sliceper convertire la attributesproprietà in array

La attributesproprietà dei nodi DOM è a NamedNodeMap, che è un oggetto simile ad una matrice.

Un oggetto simile a una matrice è un oggetto che ha una lengthproprietà e i cui nomi delle proprietà sono elencati, ma che altrimenti ha i suoi metodi e non eredita daArray.prototype

Il slicemetodo può essere utilizzato per convertire oggetti simili ad array in un nuovo 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
Restituirà array di oggetti e non di nomi di attributi come stringhe, però
Przemek,

1
L'OP non ha specificato una matrice di nomi come stringhe: "Voglio mettere tutti gli attributi in un elemento HTML in una matrice". Questo fa quello.
gfullam,

OK, ha senso
Przemek,

1
Durante l'iterazione degli elementi in attrs, è possibile accedere al nome dell'attributo con la nameproprietà sull'elemento.
tyler.frankenstein,

3

Questo approccio funziona bene se è necessario ottenere tutti gli attributi con nome e valore negli oggetti restituiti in un array.

Esempio di output:

[
    {
        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>

Se desideri solo una matrice di nomi di attributi per quell'elemento, puoi semplicemente mappare i risultati:

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

2

La risposta di Roland Bouman è il modo migliore e semplice di Vaniglia. Ho notato alcuni tentativi di plug-in jQ, ma non mi sono sembrati abbastanza "pieni", quindi l'ho fatto da solo. L'unica battuta d'arresto finora è stata l'impossibilità di accedere agli attrs aggiunti dinamicamente senza chiamare direttamente elm.attr('dynamicAttr'). Tuttavia, questo restituirà tutti gli attributi naturali di un oggetto jQuery.

Il plugin utilizza una semplice chiamata in stile jQuery:

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

Puoi anche aggiungere un secondo parametro stringa per ottenere solo un attr specifico. Questo non è davvero necessario per la selezione di un elemento, poiché jQuery fornisce già $(elm).attr('name'), tuttavia, la mia versione di un plugin consente più ritorni. Quindi, ad esempio, una chiamata come

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

Si tradurrà in un []ritorno di array di oggetti {}. Ogni oggetto sarà simile a:

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

Collegare

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

Aderito

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

Modi molto più concisi per farlo:

Vecchio modo (IE9 +):

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

Modo ES6 (Edge 12+):

[...document.querySelector(/* … */).attributes].map(attr => attr.nodeName);
  • document.querySelector()restituisce il primo elemento all'interno del documento che corrisponde al selettore specificato.
  • Element.attributesrestituisce un oggetto NamedNodeMap contenente gli attributi assegnati dell'elemento HTML corrispondente.
  • [].map() crea un nuovo array con i risultati della chiamata di una funzione fornita su ogni elemento dell'array chiamante.

demo:


1

questo aiuta?

Questa proprietà restituisce tutti gli attributi di un elemento in un array per te. Ecco un esempio

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>

Per ottenere gli attributi di molti elementi e organizzarli, suggerisco di creare una matrice di tutti gli elementi che si desidera scorrere in sequenza e quindi creare una matrice secondaria per tutti gli attributi di ciascun elemento in sequenza.

Questo è un esempio di uno script che eseguirà il ciclo tra gli elementi raccolti e stamperà due attributi. Questo script presuppone che ci saranno sempre due attributi, ma puoi risolverlo facilmente con un'ulteriore mappatura.

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

Ogni risposta qui manca la soluzione più semplice usando il metodo dell'elemento getAttributeNames !

Recupera i nomi di tutti gli attributi correnti dell'elemento come una normale matrice, che è quindi possibile ridurre a un piacevole oggetto di chiavi / valori.

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

Immagina di avere un elemento HTML come di seguito:

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

Un modo per ottenere tutti gli attributi è convertirli in un array:

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)

E sotto c'è la stringa che otterrai (dall'esempio), che include tutti gli attributi:

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

0

Prova qualcosa del genere

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

e quindi ottenere tutti gli attributi

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

per array di attributi utilizzare

    // ["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;
        }
    }

avere <div id="mydiv" a='1' b='2'>...</div> può usare

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

0

Molto semplice. Hai solo bisogno di passare in rassegna l'elemento degli attributi e spingere i loro nodeValues ​​in un array:

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

let arr = Array();

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

Se si desidera il nome dell'attributo, è possibile sostituire "nodeValue" con "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

Conversione di attributi in oggetti

* Richiede: 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
}

Questo convertirà tutti gli attributi HTML in un oggetto nidificato

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

Risultato: {custom:{nested:{path1:"value1",path2:"value2"}}}

Se parseJson è impostato su true i valori json verranno convertiti in oggetti


-8

In javascript:

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

Per accedere ai nomi e ai valori degli attributi:

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

Passare attraverso tutti gli elementi della campata sarebbe troppo lento
0-0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.