使用Javascript/jQuery获取HTML元素的所有属性

192

我想把一个 Html 元素中的所有属性放到一个数组里面:

比如,我有一个 jQuery 对象,它的 HTML 代码如下:

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

现在有一种方法是使用此处描述的XML解析器,但我需要知道如何获取对象的HTML代码。

另一种方法是使用jQuery,但是该如何操作? 属性数量和名称是通用的。

谢谢。

顺便说一下:我无法使用document.getelementbyid或类似方法访问元素。

20个回答

247
如果你只想获取DOM属性,那么在元素本身上使用attributes节点列表可能更简单:
var el = document.getElementById("someId");
for (var i = 0, atts = el.attributes, n = atts.length, arr = []; i < n; i++){
    arr.push(atts[i].nodeName);
}

请注意,这将仅填充数组中的属性名称。如果需要属性值,您可以使用nodeValue 属性:

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

问题在于我无法使用getElementById,它是一个jQuery对象。 有没有办法让getelementbyclassname在像jQuery一样的上下文中工作? - k0ni
4
你可以使用 getElementById - var el = document.getElementById($(myObj).attr("id"));。该语句的作用是获取具有特定 ID 的 HTML 元素,并将其分配给变量 el,其中 $(myObj).attr("id") 用于从 jQuery 对象中获取元素的 ID 属性。 - Sampson
46
通过使用get方法,您可以从jQuery对象中获取DOM对象...例如:var obj = $('#example').get(0); - Matt Huggins
3
@k0ni - 你可以使用例如 var atts = $(myObject)[0].attributes; 的方式吗? - Ralph Cowling
13
警告:在IE中,它不仅会获取指定的属性,而且会获取所有可能的属性。 - Alexey Lebedev
att.nodeNameatt.nodeValue是已弃用的属性,可能会显示控制台警告。首选属性是att.nameatt.value(但您可能需要回退到旧属性)。 - kumar303

74

您可以使用这个简单的插件,像这样 $('#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
请注意:这只会暴露选择器的第一个元素。 - Brett Veenstra
我进行了测试,它可以与动态添加的属性(Chrome)一起正常工作。 - CodeToad

60

简单:

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

8
Google Chrome 表示 Attr.nodeValue 已被弃用,应使用 value。因此代码可以简写为 this.name + ':' + this.value。更多详情请参考 The Attr Interface - Thai

21
因为在IE7中,elem.attributes会列出所有可能的属性,而不仅仅是当前存在的属性,所以我们必须测试属性值。这个插件可以在所有主流浏览器中使用:
(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);

用法:

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

1
这里有一个错别字 -- 第6行的el.get(0)应该是elem.get(0)。 - Graham Charles
从我的经验来看,这实际上比这更加复杂。至少在某些情况下是这样的。例如,这是否包括一个名为"dataFld"且值为"null"(字符串值)的属性,还是会将其排除在外? - Shahar 'Dawn' Or
它无法与动态添加的属性一起使用,因为属性和属性值并不总是同步的。 - DUzun

18

设置器和获取器!

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

使用:

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

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

2
很好,我最喜欢这个答案。与 jQuery.attr 完美地契合。 - Scott Rippey
1
两个建议:您能否更新以使用“非缩小”的变量名称?而且我看到您在setter中使用了jQuery.attr,但在getter中使用它可能会更有益。 - Scott Rippey
还有一件小事 - 在你的第一个for()语句后面不应该有分号。 - jbyrd

13

有一个更好的答案

我推荐使用Tim Kindberg的答案, 该答案使用getAttributeNames()getAttribute(name), MDN表示这是一种内存高效且性能良好的访问Element.attributes的替代方法

以下是我原始的和更新后的答案,如果它们提供了某些好处,则仍然保留。


使用Array.from()或展开运算符...

更新:在2015年6月的ECMA-262第六版中添加了Array.from()和展开运算符...,现在具有普遍的现代浏览器支持。

请参见MDN › Array.from()展开语法 (...)

var elem  = document.querySelector('[name=test]'),
    attrs = elem.attributes;

console.log('Array.from(attrs)');
Array.from(attrs).forEach(({ name, value }) => {
    console.log(`    ${name}: ${value}`);
})

console.log('[...attrs]');
[...attrs].forEach(({ name, value }) => {
    console.log(`    ${name}: ${value}`);
})
<span name="test" message="test2">See console.</span>


注意:以下是旧版答案。它仍然有效,但较新的Array.from()方法现在更受欢迎。这现在可以被认为是为支持ES2015之前的目标而设计的polyfill。
使用.sliceattributes属性转换为数组
DOM节点的attributes属性是NamedNodeMap,它是一个类似数组的对象。
类似数组的对象是具有length属性且其属性名可枚举,但其方法是自身的且不继承自Array.prototype的对象。 可以使用slice方法将类似数组的对象转换为新数组

var elem  = document.querySelector('[name=test]'),
    attrs = elem.attributes;

console.log('Array.prototype.slice.call(attrs)');
Array.prototype.slice.call(attrs).forEach(
    function (cur) {
        console.log(cur.name + ': ' + cur.value);
    }
)
<span name="test" message="test2">See console.</span>


1
它将返回对象数组,而不是属性名称的字符串。 - Przemek
1
OP没有指定一个字符串名称的数组:“我想把Html元素中的所有属性放入一个数组中。” 这个代码可以实现。 - gfullam
好的,明白了。 - Przemek
1
在迭代attrs中的项目时,您可以使用项目上的name属性访问属性的名称。 - tyler.frankenstein
2
[...elem.attributes] - Davi Lima

10

这里的每个答案都忽略了使用getAttributeNames元素方法的最简单解决方案!

它将当前元素的所有属性名称作为常规数组检索,然后您可以将其缩减为一个漂亮的键/值对象。

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>


注意:不支持IE 11及以下版本。 - Tim Kindberg

8
非常简单。您只需要循环遍历属性元素并将它们的nodeValues推入数组中:
let att = document.getElementById('id');

let arr = Array();

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

如果您想获取属性的名称,可以将'nodeValue'替换为'nodeName'。

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

let arr = Array();

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

5
更简洁的方法如下:

旧的方法(IE9+):

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

ES6方法(Edge 12+):

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

Demo:

console.log(
  [...document.querySelector('img').attributes].map(attr => attr.nodeName)
);
/* Output console formatting */
.as-console-wrapper { position: absolute; top: 0; }
<img src="…" alt="…" height="…" width="…"/>


3

如果您需要获取返回数组中所有带有名称和值的属性,则此方法非常有效。

示例输出:

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

如果你只想获取该元素的属性名数组,你可以使用map方法来获取结果:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接