Obtenga todos los atributos de un elemento HTML con Javascript / jQuery

161

Quiero poner todos los atributos en un elemento Html en una matriz: como si tuviera un objeto jQuery, que html se ve así:

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

ahora una forma es usar el analizador xml descrito aquí , pero luego necesito saber cómo obtener el código html de mi objeto.

la otra forma es hacerlo con jquery, pero ¿cómo? El número de atributos y los nombres son genéricos.

Gracias

Por cierto: no puedo acceder al elemento con document.getelementbyid o algo similar.

k0ni
fuente

Respuestas:

218

Si solo desea los atributos DOM, probablemente sea más simple usar la attributeslista de nodos en el elemento en sí:

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

Tenga en cuenta que esto llena la matriz solo con nombres de atributos. Si necesita el valor del atributo, puede usar la nodeValuepropiedad:

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);
}
Roland Bouman
fuente
El problema es que no puedo usar getElementById, es un objeto jquery. ¿Hay alguna manera de que pueda hacer getelementbyclassname dentro de un contexto como en jquery?
k0ni
44
Puede usar getElementById-var el = document.getElementById($(myObj).attr("id"));
Sampson
45
Puede obtener el objeto DOM de un objeto jQuery a través del getmétodo ... por ejemplo:var obj = $('#example').get(0);
Matt Huggins
3
@ k0ni: ¿podría usar, por ejemplo, var atts = $ (myObject) [0] .attributes; ?
Ralph Cowling
12
Advertencia: en IE esto no solo se especifica, sino todos los atributos posibles
Alexey Lebedev
70

Puede usar este complemento simple como $ ('# 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);
manRo
fuente
44
FYI: Esto solo expone el primer elemento del selector.
Brett Veenstra
Probé
57

Sencillo:

var element = $("span[name='test']");
$(element[0].attributes).each(function() {
console.log(this.nodeName+':'+this.nodeValue);});
Aki143S
fuente
¿Alguna desventaja de esto?
rzr
77
Attr.nodeValueestá en desuso a favor de value, dice Google Chrome. Entonces esto podría ser this.name + ':' + this.value. La interfaz Attr
Thai
20

Debido a que en IE7 elem.attributes enumera todos los atributos posibles, no solo los actuales, tenemos que probar el valor del atributo. Este complemento funciona en todos los principales navegadores:

(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();
DUzun
fuente
1
Error tipográfico en esto: el.get (0) en la línea 6 debe ser elem.get (0)
Graham Charles
Según mi experiencia, ahora esto es en realidad un poco más complejo que esto. Al menos en algunos casos. Por ejemplo, ¿incluirá esto un atributo llamado 'dataFld' con valor 'nulo' (valor de cadena) o lo excluiría?
mightyiam
No funciona con propiedades agregadas dinámicamente, porque las propiedades y los atributos no siempre están sincronizados.
DUzun
18

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

Utilizar:

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

// Getter
var attrs = $('#element').attrs();
Eduardo Cuomo
fuente
2
Bien, me gusta esta respuesta la mejor. Encaja perfectamente bien con jQuery.attr.
Scott Rippey
1
Dos recomendaciones: ¿Puedes actualizar para usar nombres de variables "no minificados"? Y veo que lo estás usando jQuery.attren el setter, pero probablemente sería beneficioso usarlo también en el getter.
Scott Rippey
Además, algo pequeño: no debería haber un punto y coma después de su primera declaración for ().
jbyrd
6

Use .slicepara convertir la attributespropiedad a Array

La attributespropiedad de los nodos DOM es a NamedNodeMap, que es un objeto tipo Array.

Un objeto tipo Array es un objeto que tiene una lengthpropiedad y cuyos nombres de propiedad se enumeran, pero de lo contrario tiene sus propios métodos y no hereda deArray.prototype

El slicemétodo se puede utilizar para convertir objetos de tipo Array en un nuevo 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>

gfullam
fuente
1
Sin embargo, devolverá una serie de objetos y no de nombres de atributos como cadenas
Przemek
1
El OP no especificó una matriz de nombres como cadenas: "Quiero poner todos los atributos en un elemento Html en una matriz". Esto hace eso.
gfullam
OK, tiene sentido
Przemek
1
Al iterar sobre los elementos attrs, puede acceder al nombre del atributo con la namepropiedad del elemento.
tyler.frankenstein
3

Este enfoque funciona bien si necesita obtener todos los atributos con nombre y valor en los objetos devueltos en una matriz.

Salida de ejemplo:

[
    {
        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 solo desea una matriz de nombres de atributos para ese elemento, puede simplemente asignar los resultados:

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

La respuesta de Roland Bouman es la mejor y más simple manera de Vanilla. Noté algunos intentos de enchufes jQ, pero simplemente no me parecieron lo suficientemente "llenos", así que hice el mío. El único inconveniente hasta ahora ha sido la incapacidad de acceder a los atributos agregados dinámicamente sin llamar directamente elm.attr('dynamicAttr'). Sin embargo, esto devolverá todos los atributos naturales de un objeto de elemento jQuery.

El complemento utiliza llamadas de estilo jQuery simples:

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

También puede agregar un segundo parámetro de cadena para obtener solo un atributo específico. Esto no es realmente necesario para la selección de un elemento, ya que jQuery ya proporciona $(elm).attr('name'), sin embargo, mi versión de un complemento permite múltiples retornos. Entonces, por ejemplo, una llamada como

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

Resultará en una matriz de []retorno de objetos {}. Cada objeto se verá así:

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

Enchufar

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

Cumplido

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

SpYk3HH
fuente
2

Maneras mucho más concisas de hacerlo:

A la antigua usanza (IE9 +):

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

Forma ES6 (Edge 12+):

[...document.querySelector(/* … */).attributes].map(attr => attr.nodeName);
  • document.querySelector()devuelve el primer elemento dentro del documento que coincide con el selector especificado.
  • Element.attributesdevuelve un objeto NamedNodeMap que contiene los atributos asignados del elemento HTML correspondiente.
  • [].map() crea una nueva matriz con los resultados de llamar a una función proporcionada en cada elemento de la matriz que realiza la llamada.

Manifestación:

Przemek
fuente
1

¿Esto ayuda?

Esta propiedad devuelve todos los atributos de un elemento en una matriz para usted. Aquí hay un ejemplo.

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>

Para obtener los atributos de muchos elementos y organizarlos, sugiero hacer una matriz de todos los elementos que desea recorrer y luego crear una matriz secundaria para todos los atributos de cada elemento en bucle.

Este es un ejemplo de un script que recorrerá los elementos recopilados e imprimirá dos atributos. Este script supone que siempre habrá dos atributos, pero puede solucionarlo fácilmente con una asignación adicional.

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>

www139
fuente
1

¡A cada respuesta aquí le falta la solución más simple usando el método del elemento getAttributeNames !

Recupera los nombres de todos los atributos actuales del elemento como una matriz regular, que luego puede reducir a un buen objeto de claves / valores.

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>

Tim Kindberg
fuente
1

Imagina que tienes un elemento HTML como el siguiente:

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

Una forma de obtener todos los atributos es convertirlos en una matriz:

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)

Y a continuación se muestra la cadena que obtendrá (del ejemplo), que incluye todos los atributos:

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

Intenta algo como esto

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

y luego obtener todos los atributos

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

para una variedad de atributos usar

    // ["id","[href]","class","(click)","data-hello"]
    Object.keys(getAttributes(foo))
weroro
fuente
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;
        }
    }

tener <div id="mydiv" a='1' b='2'>...</div> puede usar

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

Muy simple. Solo necesita recorrer el elemento de atributos e insertar sus valores de nodo en una matriz:

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

let arr = Array();

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

Si desea el nombre del atributo, puede reemplazar 'nodeValue' por 'nodeName'.

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

let arr = Array();

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

Atributos para la conversión de objetos

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

Esto convertirá todos los atributos html en un objeto anidado

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

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

Si parseJson se establece en verdaderos valores json se convertirán en objetos

Dieter Gribnitz
fuente
-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;
  }
}

Para acceder a los nombres y valores de los atributos:

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

fuente
Ir a través de todos los elementos span sería demasiado lento
0-0