Get all Attributes from a HTML element with Javascript/jQuery

Viewed 320518

I want to put all attributes in a Html element into an array: like i have a jQuery Object, whichs html looks like this:

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

now one way is to use the xml parser described here, but then i need to know how to get the html code of my object.

the other way is to make it with jquery, but how? the number of attributes and the names are generic.

Thanks

Btw: I can't access the element with document.getelementbyid or something similar.

19 Answers

If you just want the DOM attributes, it's probably simpler to use the attributes node list on the element itself:

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

Note that this fills the array only with attribute names. If you need the attribute value, you can use the nodeValue property:

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

Every answer here is missing the simplest solution using the getAttributeNames element method!

It retrieves the names of all the element's current attributes as a regular Array, that you can then reduce to a nice object of keys/values.

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>

Very simple. You just need to loop over the attributes element and push their nodeValues into an array:

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

let arr = Array();

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

If you want the name of the attribute you can replace 'nodeValue' for 'nodeName'.

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

let arr = Array();

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

Imagine you've got an HTML element like below:

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

One way you can get all attributes of it is to convert them into an 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)

And below is the string that what you'll get (from the example), which includes all attributes:

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

Try something like this

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

and then get all attributes

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

for array of attributes use

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

Attributes to Object conversion

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

This will convert all html attributes to a nested object

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

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

If parseJson is set to true json values will be converted to objects

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

having <div id="mydiv" a='1' b='2'>...</div> can use

mydiv.getA() // {id:"mydiv",a:'1',b:'2'}
function getElementHTMLAttributes(elementId) {
    var element = document.getElementById(elementId);
    if (element != undefined) {
      var elementHTMLAttributes = {};
      for (var attr, i = 0, attrs = element.attributes, n = attrs.length; i < n; i++){
        attr = attrs[i];
        elementHTMLAttributes[attr.nodeName] = attr.nodeValue;
      }
    return elementHTMLAttributes;
    }
}

Element.attributes returns a NamedNodeMap of attributes of that HTMLElement which is mildly a JavaScript Map. Hence supposing

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

you can create an object from the NamedNodeMap like below:

const el = document.querySelector('#mySpan')
const attrs = Object.fromEntries(Array.from(el.attributes).map(item => [item.name, item.value]))

and then access an individual attribute by the dot notation for object properties:

console.log(attrs.name) // "test"
console.log(attrs.messsage) // "test2"

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

To access the attributes names and values:

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