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.

k0ni
źródło

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);
}
Roland Bouman
źródło
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);
manRo
źródło
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);});
Aki143S
źródło
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();
DUzun
źródło
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();
Eduardo Cuomo
źródło
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>

gfullam
źródło
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"]
KevBot
źródło
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

SpYk3HH
źródło
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:

Przemek
źródło
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>

www139
źródło
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>

Tim Kindberg
źródło
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"
Yuci
źródło
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))
weroro
źródło
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'}
bortunac
źródło
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);
}
Berg_Durden
źródło
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

Dieter Gribnitz
źródło
-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

źródło
Przejście przez wszystkie elementy przęsła byłoby zbyt wolne
0-0