Pobierz wszystkie atrybuty z elementu HTML za pomocą Javascript / jQuery


161

Chcę umieścić wszystkie atrybuty w elemencie HTML w tablicy: tak jak mam obiekt jQuery, który html wygląda tak:

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

teraz jednym ze sposobów jest użycie opisanego tutaj parsera xml , ale potem muszę wiedzieć, jak uzyskać kod HTML mojego obiektu.

innym sposobem jest zrobienie tego za pomocą jquery, ale jak? liczba atrybutów i nazwy są ogólne.

Dzięki

Btw: Nie mogę uzyskać dostępu do elementu z document.getelementbyid lub czymś podobnym.

Odpowiedzi:


218

Jeśli chcesz tylko atrybuty DOM, prawdopodobnie łatwiej będzie użyć attributeslisty węzłów w samym elemencie:

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

Zauważ, że to wypełnia tablicę tylko nazwami atrybutów. Jeśli potrzebujesz wartości atrybutu, możesz użyć nodeValuewłaściwości:

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

Problem polega na tym, że nie mogę użyć getElementById, jest to obiekt jquery. czy jest sposób, w jaki mogę ustawić getelementbyclassname w kontekście takim jak w jquery?
k0ni

4
Możesz użyć getElementById-var el = document.getElementById($(myObj).attr("id"));
Sampson

45
Możesz pobrać obiekt DOM z obiektu jQuery za pomocą getmetody ... np .:var obj = $('#example').get(0);
Matt Huggins

3
@ k0ni - czy mógłbyś użyć np. var atts = $ (myObject) [0] .attributes; ?
Ralph Cowling

12
Ostrzeżenie: w IE jest to nie tylko określone, ale wszystkie możliwe atrybuty
Alexey Lebedev

70

Możesz użyć tej prostej wtyczki jako $ ('# 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: To ujawnia tylko pierwszy element selektora.
Brett Veenstra

Przetestowałem i działa z dynamicznie dodanymi atrybutami (chrome)
CodeToad

57

Prosty:

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

Jakieś wady tego?
rzr

7
Attr.nodeValuejest przestarzały na korzyść value, mówi Google Chrome. Więc to może być this.name + ':' + this.value. Interfejs Attr
tajski

20

Ponieważ w IE7 elem.attributes wymienia wszystkie możliwe atrybuty, nie tylko te obecne, musimy przetestować wartość atrybutu. Ta wtyczka działa we wszystkich głównych przeglądarkach:

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

Stosowanie:

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

1
Literówka w tym - el.get (0) w linii 6 powinna mieć postać elem.get (0).
Graham Charles

Z mojego obecnego doświadczenia wynika, że ​​jest to nieco bardziej złożone niż to. Przynajmniej w niektórych przypadkach. Na przykład, czy będzie to obejmować atrybut o nazwie „dataFld” o wartości „null” (wartość ciągu), czy też go wykluczy?
mightyiam

Nie działa z dynamicznie dodawanymi właściwościami, ponieważ właściwości i atrybuty nie zawsze są zsynchronizowane.
DUzun

18

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

Posługiwać się:

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

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

2
Fajnie, ta odpowiedź podoba mi się najbardziej. Idealnie pasuje do jQuery.attr.
Scott Rippey,

1
Dwa zalecenia: czy możesz zaktualizować, aby używały „niezminifikowanych” nazw zmiennych? Widzę, że używasz go jQuery.attrw seterze, ale prawdopodobnie byłoby korzystne użycie go również w getterze.
Scott Rippey,

Mała rzecz - po pierwszej instrukcji for () nie powinno być średnika.
jbyrd

6

Służy .slicedo konwersji attributeswłaściwości na Array

attributesWłaściwość węzłów DOM jest NamedNodeMap, która jest tablicą podobny obiekt.

Obiekt podobny do tablicy to obiekt, który ma lengthwłaściwość i którego nazwy właściwości są wyliczane, ale poza tym ma własne metody i nie dziedziczy poArray.prototype

sliceMetoda może być użyty do konwersji obiektów Array podobny do nowej tablicy .

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
Zwróci jednak tablicę obiektów, a nie nazwy atrybutów jako ciągi znaków
Przemek

1
OP nie określił tablicy nazw jako ciągów znaków: „Chcę umieścić wszystkie atrybuty elementu HTML w tablicy”. Robi to.
gfullam

OK, ma sens
Przemek

1
Podczas iteracji po elementach w programie attrsmożesz uzyskać dostęp do nazwy atrybutu z namewłaściwością elementu.
tyler.frankenstein

3

To podejście działa dobrze, jeśli chcesz pobrać wszystkie atrybuty z nazwą i wartością w obiektach zwracanych w tablicy.

Przykładowe dane wyjściowe:

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

Jeśli chcesz mieć tylko tablicę nazw atrybutów dla tego elementu, możesz po prostu zmapować wyniki:

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

2

Roland Bouman „s odpowiedź jest najlepszy, prosty Vanilla sposób. Zauważyłem kilka prób wtyczek jQ, ale po prostu nie wydawały mi się one wystarczająco „pełne”, więc stworzyłem własne. Jak dotąd jedyną przeszkodą była niemożność uzyskania dostępu do dynamicznie dodanych atrybutów bez bezpośredniego wywołania elm.attr('dynamicAttr'). Jednak zwróci to wszystkie naturalne atrybuty obiektu elementu jQuery.

Wtyczka używa prostego wywołania w stylu jQuery:

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

Możesz również dodać drugi parametr ciągu, aby uzyskać tylko jeden określony atrybut. Nie jest to naprawdę potrzebne do wyboru jednego elementu, ponieważ jQuery już zapewnia $(elm).attr('name'), jednak moja wersja wtyczki pozwala na wiele zwrotów. Na przykład połączenie typu

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

Spowoduje to []zwrócenie tablicy obiektów {}. Każdy obiekt będzie wyglądał następująco:

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

Podłącz

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

Spełnione

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

O wiele bardziej zwięzłe sposoby:

Stary sposób (IE9 +):

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

Sposób ES6 (Edge 12+):

[...document.querySelector(/* … */).attributes].map(attr => attr.nodeName);

Próbny:


1

czy to pomaga?

Ta właściwość zwraca wszystkie atrybuty elementu do tablicy. Oto przykład.

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>

Aby uzyskać atrybuty wielu elementów i je uporządkować, proponuję utworzyć tablicę wszystkich elementów, przez które chcesz przechodzić, a następnie utworzyć tablicę podrzędną dla wszystkich atrybutów każdego elementu przechodzącego w pętli.

To jest przykład skryptu, który przejdzie przez zebrane elementy i wydrukuje dwa atrybuty. Ten skrypt zakłada, że ​​zawsze będą dwa atrybuty, ale można to łatwo naprawić poprzez dalsze mapowanie.

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

W każdej odpowiedzi brakuje najprostszego rozwiązania przy użyciu metody elementu getAttributeNames !

Pobiera nazwy wszystkich bieżących atrybutów elementu jako zwykłą tablicę, którą można następnie zredukować do ładnego obiektu kluczy / wartości.

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

Wyobraź sobie, że masz element HTML, jak poniżej:

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

Jednym ze sposobów uzyskania wszystkich atrybutów jest przekonwertowanie ich na tablicę:

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)

A poniżej znajduje się ciąg, który otrzymasz (z przykładu), który zawiera wszystkie atrybuty:

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

0

Spróbuj czegoś takiego

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

a następnie pobierz wszystkie atrybuty

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

dla tablicy użycia atrybutów

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

mając <div id="mydiv" a='1' b='2'>...</div> może używać

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

0

Bardzo prosty. Wystarczy, że przejdziesz pętlę nad elementem atrybutów i wepchniesz ich wartości nodeValues ​​do tablicy:

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

let arr = Array();

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

Jeśli chcesz nazwę atrybutu, możesz zamienić „nodeValue” na „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

Atrybuty konwersji obiektu

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

Spowoduje to przekonwertowanie wszystkich atrybutów HTML na obiekt zagnieżdżony

Przykładowy kod HTML: <div custom-nested-path1="value1" custom-nested-path2="value2"></div>

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

Jeśli parseJson jest ustawiona na true, wartości json zostaną przekonwertowane na obiekty


-8

W javascript:

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

Aby uzyskać dostęp do nazw i wartości atrybutów:

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

Przejście przez wszystkie elementy przęsła byłoby zbyt wolne
0-0
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.