Holen Sie sich alle Attribute aus einem HTML-Element mit Javascript / jQuery

161

Ich möchte alle Attribute in einem HTML-Element in ein Array einfügen: Als hätte ich ein jQuery-Objekt, dessen HTML folgendermaßen aussieht:

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

Jetzt besteht eine Möglichkeit darin, den hier beschriebenen XML-Parser zu verwenden , aber dann muss ich wissen, wie ich den HTML-Code meines Objekts erhalte.

der andere weg ist es mit jquery zu machen, aber wie? Die Anzahl der Attribute und die Namen sind generisch.

Vielen Dank

Übrigens: Ich kann mit document.getelementbyid oder ähnlichem nicht auf das Element zugreifen.

k0ni
quelle

Antworten:

218

Wenn Sie nur die DOM-Attribute möchten, ist es wahrscheinlich einfacher, die attributesKnotenliste für das Element selbst zu verwenden:

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

Beachten Sie, dass dies das Array nur mit Attributnamen füllt. Wenn Sie den Attributwert benötigen, können Sie die nodeValueEigenschaft verwenden:

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
quelle
Das Problem ist, dass ich getElementById nicht verwenden kann, es ist ein jquery-Objekt. Gibt es eine Möglichkeit, getelementbyclassname in einem Kontext wie bei jquery zu erstellen?
k0ni
4
Sie können getElementById-var el = document.getElementById($(myObj).attr("id"));
Sampson
45
Sie können das DOM-Objekt von einem jQuery-Objekt über die getMethode abrufen ... zB:var obj = $('#example').get(0);
Matt Huggins
3
@ k0ni - könnten Sie zB var atts = $ (myObject) [0] .attributes verwenden; ?
Ralph Cowling
12
Warnung: In IE wird dies nicht nur angegeben, sondern alle möglichen Attribute
Alexey Lebedev
70

Sie können dieses einfache Plugin als $ ('# some_id') verwenden. 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
quelle
4
Zu Ihrer Information: Dies macht nur das erste Element des Selektors sichtbar.
Brett Veenstra
Ich habe getestet und es funktioniert mit dynamisch hinzugefügten Attributen (Chrome)
CodeToad
57

Einfach:

var element = $("span[name='test']");
$(element[0].attributes).each(function() {
console.log(this.nodeName+':'+this.nodeValue);});
Aki143S
quelle
Irgendwelche Nachteile davon?
Rzr
7
Attr.nodeValueist zugunsten von veraltet value, sagt Google Chrome. Das könnte also sein this.name + ':' + this.value. Die Attr-Schnittstelle
Thai
20

Da in IE7 elem.attributes alle möglichen Attribute auflistet, nicht nur die aktuellen, müssen wir den Attributwert testen. Dieses Plugin funktioniert in allen gängigen Browsern:

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

Verwendung:

var attribs = $('#some_id').getAttributes();
DUzun
quelle
1
Tippfehler in diesem - el.get (0) in Zeile 6 sollte elem.get (0) sein.
Graham Charles
Nach meiner Erfahrung ist dies tatsächlich etwas komplexer. Zumindest in einigen Fällen. Enthält dies beispielsweise ein Attribut mit dem Namen 'dataFld' mit dem Wert 'null' (Zeichenfolgenwert) oder wird es ausgeschlossen?
Mightyiam
Es funktioniert nicht mit dynamisch hinzugefügten Eigenschaften, da Eigenschaften und Attribute nicht immer synchron sind.
DUzun
18

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

Verwenden:

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

// Getter
var attrs = $('#element').attrs();
Eduardo Cuomo
quelle
2
Schön, ich mag diese Antwort am besten. Passt perfekt dazu jQuery.attr.
Scott Rippey
1
Zwei Empfehlungen: Können Sie ein Update durchführen, um "nicht minimierte" Variablennamen zu verwenden? Und ich sehe, dass Sie jQuery.attrim Setter verwenden, aber es wäre wahrscheinlich vorteilhaft, es auch im Getter zu verwenden.
Scott Rippey
Auch eine kleine Sache - nach Ihrer ersten for () -Anweisung sollte kein Semikolon stehen.
17.
6

Verwenden Sie .slice, um die zu konvertierenattributes Eigenschaft in Array

Die attributesEigenschaft von DOM-Knoten ist aNamedNodeMap , ein Array-ähnliches Objekt.

Ein Array-ähnliches Objekt ist ein Objekt, das eine lengthEigenschaft hat und dessen Eigenschaftsnamen aufgelistet sind, ansonsten aber eigene Methoden hat und nicht von ihnen erbtArray.prototype

Die sliceMethode kann verwendet werden, um Array-ähnliche Objekte in ein neues Array zu konvertieren .

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
quelle
1
Es wird jedoch ein Array von Objekten und nicht von Attributnamen als Zeichenfolgen zurückgeben
Przemek
1
Das OP hat kein Array von Namen als Zeichenfolgen angegeben: "Ich möchte alle Attribute in einem HTML-Element in ein Array einfügen." Das macht das.
Gfullam
OK, macht Sinn
Przemek
1
Während Sie die Elemente in durchlaufen attrs, können Sie auf den Namen des Attributs mit der nameEigenschaft für das Element zugreifen .
tyler.frankenstein
3

Dieser Ansatz funktioniert gut, wenn Sie alle Attribute mit Namen und Wert in Objekten abrufen müssen, die in einem Array zurückgegeben werden.

Beispielausgabe:

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

Wenn Sie nur ein Array von Attributnamen für dieses Element möchten, können Sie einfach die Ergebnisse zuordnen:

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

Roland Bouman ‚s Antwort ist die beste, einfache Vanilla Art und Weise. Ich bemerkte einige Versuche mit jQ-Steckern, aber sie schienen mir einfach nicht "voll" genug zu sein, also machte ich meine eigenen. Der einzige Rückschlag war bisher die Unfähigkeit, auf dynamisch hinzugefügte Attribute zuzugreifen, ohne direkt aufzurufenelm.attr('dynamicAttr') . Dies gibt jedoch alle natürlichen Attribute eines jQuery-Elementobjekts zurück.

Das Plugin verwendet einfache Aufrufe im jQuery-Stil:

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

Sie können auch einen zweiten Zeichenfolgenparameter hinzufügen, um nur einen bestimmten attr zu erhalten. Dies wird für eine Elementauswahl nicht wirklich benötigt, da jQuery bereits bereitstellt $(elm).attr('name'). Meine Version eines Plugins ermöglicht jedoch mehrere Rückgaben. So zum Beispiel ein Anruf wie

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

Führt zu einer Array- []Rückgabe von Objekten {}. Jedes Objekt sieht folgendermaßen aus:

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

Plugin

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

Erfüllt

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

Viel prägnantere Möglichkeiten:

Alter Weg (IE9 +):

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

ES6-Weg (Edge 12+):

[...document.querySelector(/* … */).attributes].map(attr => attr.nodeName);
  • document.querySelector()Gibt das erste Element im Dokument zurück, das dem angegebenen Selektor entspricht.
  • Element.attributesGibt ein NamedNodeMap- Objekt zurück, das die zugewiesenen Attribute des entsprechenden HTML-Elements enthält.
  • [].map() Erstellt ein neues Array mit den Ergebnissen des Aufrufs einer bereitgestellten Funktion für jedes Element im aufrufenden Array.

Demo:

Przemek
quelle
1

Hilft das?

Diese Eigenschaft gibt alle Attribute eines Elements für Sie in ein Array zurück. Hier ist ein Beispiel.

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>

Um die Attribute vieler Elemente abzurufen und zu organisieren, empfehle ich, ein Array aller Elemente zu erstellen, die Sie durchlaufen möchten, und dann ein Unterarray für alle Attribute jedes Elements zu erstellen, das durchlaufen wird.

Dies ist ein Beispiel für ein Skript, das die gesammelten Elemente durchläuft und zwei Attribute druckt. In diesem Skript wird davon ausgegangen, dass immer zwei Attribute vorhanden sind. Sie können dies jedoch problemlos durch weitere Zuordnung beheben.

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
quelle
1

Bei jeder Antwort fehlt die einfachste Lösung mit getAttributeNames !

Es ruft die Namen aller aktuellen Attribute des Elements als reguläres Array ab, das Sie dann auf ein schönes Objekt mit Schlüsseln / Werten reduzieren können.

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
quelle
1

Stellen Sie sich vor, Sie haben ein HTML-Element wie das folgende:

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

Eine Möglichkeit, alle Attribute zu erhalten, besteht darin, sie in ein Array zu konvertieren:

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)

Und unten ist die Zeichenfolge, die Sie erhalten (aus dem Beispiel), die alle Attribute enthält:

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

Versuchen Sie so etwas

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

und dann alle Attribute erhalten

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

für ein Array von Attributen verwenden

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

haben <div id="mydiv" a='1' b='2'>...</div> kann verwenden

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

Sehr einfach. Sie müssen nur das Attributelement durchlaufen und dessen nodeValues ​​in ein Array verschieben:

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

let arr = Array();

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

Wenn Sie den Namen des Attributs möchten, können Sie 'nodeValue' durch 'nodeName' ersetzen.

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
quelle
0

Attribute zur Objektkonvertierung

* Benötigt: 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
}

Dadurch werden alle HTML-Attribute in ein verschachteltes Objekt konvertiert

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

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

Wenn parseJson auf true gesetzt ist, werden json-Werte in Objekte konvertiert

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

So greifen Sie auf die Attributnamen und -werte zu:

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

quelle
Alle Span-Elemente zu durchlaufen wäre zu langsam
0-0