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

我想把一个 Html 元素中的所有属性放入一个数组中: 比如我有一个 jQuery 对象,它的 html 是这样的:

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

现在的一种方法是使用描述的 xml 解析器 给你,但是接下来我需要知道如何获取对象的 html 代码。

另一种方法是使用 jquery 实现,但是如何实现呢? 属性的数量和名称是通用的。

谢谢

顺便说一下: 我不能使用 document.getelementbyid 或类似的东西访问元素。

324574 次浏览

如果只需要 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);
}

在 javascript 中:

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

访问属性名称和值:

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

您可以使用这个简单的插件作为 $(’# some _ id’) . getAttritribute () ;

(function($) {
$.fn.getAttributes = function() {
var attributes = {};


if( this.length ) {
$.each( this[0].attributes, function( index, attr ) {
attributes[ attr.name ] = attr.value;
} );
}


return attributes;
};
})(jQuery);

简单:

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

因为在 IE7 elem.properties 中列出了所有可能的属性,而不仅仅是当前的属性,我们必须测试属性值。 这个插件适用于所有主流浏览器:

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

塞特和盖特!

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

罗兰布曼的 回答是最好的,简单的香草方式。我注意到有人尝试使用 jQ 插头,但是对我来说它们似乎不够“完整”,所以我自己做了一个。到目前为止,唯一的问题是无法在不直接调用 elm.attr('dynamicAttr')的情况下访问动态添加的 attrs。但是,这将返回 jQuery 元素对象的所有自然属性。

Plugin 使用简单的 jQuery 样式调用:

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

您还可以添加第二个字符串参数,以获取一个特定的 attr。这对于一个元素选择来说并不真正需要,因为 jQuery 已经提供了 $(elm).attr('name'),但是我的插件版本允许多个返回。举个例子

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

将导致返回对象 {}的数组 []。每个对象看起来像:

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

插件

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

遵命

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

/*  BEGIN PLUGIN  */
;;(function($) {
$.getAttrs || ($.extend({
getAttrs: function() {
var a = arguments,
c, b;
if (a.length)
for (x in a) switch (typeof a[x]) {
case "object":
a[x] instanceof f && (b = a[x]);
break;
case "string":
b ? c || (c = a[x]) : b = $(a[x])
}
if (b instanceof f) {
if (1 == b.length) {
for (var d = [], e = 0, g = b[0].attributes, h = g.length; e < h; e++) a = g[e], d[a.name] = a.value;
b.data("attrList", d);
c && "all" != c && (d = b.attr(c));
for (x in d) d.length++
} else d = [], c && "all" != c ? b.each(function(a) {
a = {
elm: $(this),
index: $(this).index()
};
a[c] = $(this).attr(c);
d.push(a)
}) : b.each(function(a) {
$elmRet = [];
for (var b = 0, c = this.attributes, e = c.length; b < e; b++) a = c[b], $elmRet[a.name] = a.value;
d.push({
elm: $(this),
index: $(this).index(),
attrs: $elmRet
});
$(this).data("attrList", d);
for (x in $elmRet) $elmRet.length++
});
return d
}
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);
/*  END PLUGIN  */
/*--------------------*/
$('#bob').attr('bob', 'bill');
console.log($('#bob'))
console.log(new Array(50).join(' -'));
console.log($('#bob').getAttrs('id'));
console.log(new Array(50).join(' -'));
console.log($.getAttrs('#bob'));
console.log(new Array(50).join(' -'));
console.log($.getAttrs('#bob', 'name'));
console.log(new Array(50).join(' -'));
console.log($.getAttrs('*', 'class'));
console.log(new Array(50).join(' -'));
console.log($.getAttrs('p'));
console.log(new Array(50).join(' -'));
console.log($('#bob').getAttrs('all'));
console.log($('*').getAttrs('all'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
All of below is just for stuff for plugin to test on. See developer console for more details.
<hr />
<div id="bob" class="wmd-button-bar"><ul id="wmd-button-row-27865269" class="wmd-button-row" style="display:none;">
<div class="post-text" itemprop="text">
<p>Roland Bouman's answer is the best, simple Vanilla way. I noticed some attempts at jQ plugs, but they just didn't seem "full" enough to me, so I made my own. The only setback so far has been inability to access dynamically added attrs without directly calling <code>elm.attr('dynamicAttr')</code>. However, this will return all natural attributes of a jQuery element object.</p>


<p>Plugin uses simple jQuery style calling:</p>


<pre class="default prettyprint prettyprinted"><code><span class="pln">$</span><span class="pun">(</span><span class="pln">elm</span><span class="pun">).</span><span class="pln">getAttrs</span><span class="pun">();</span><span class="pln">
</span><span class="com">// OR</span><span class="pln">
$</span><span class="pun">.</span><span class="pln">getAttrs</span><span class="pun">(</span><span class="pln">elm</span><span class="pun">);</span></code></pre>


<p>You can also add a second string param for getting just one specific attr. This isn't really needed for one element selection, as jQuery already provides <code>$(elm).attr('name')</code>, however, my version of a plugin allows for multiple returns. So, for instance, a call like</p>


<pre class="default prettyprint prettyprinted"><code><span class="pln">$</span><span class="pun">.</span><span class="pln">getAttrs</span><span class="pun">(</span><span class="str">'*'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'class'</span><span class="pun">);</span></code></pre>


<p>Will result in an array <code>[]</code> return of objects <code>{}</code>. Each object will look like:</p>


<pre class="default prettyprint prettyprinted"><code><span class="pun">{</span><span class="pln"> </span><span class="kwd">class</span><span class="pun">:</span><span class="pln"> </span><span class="str">'classes names'</span><span class="pun">,</span><span class="pln"> elm</span><span class="pun">:</span><span class="pln"> $</span><span class="pun">(</span><span class="pln">elm</span><span class="pun">),</span><span class="pln"> index</span><span class="pun">:</span><span class="pln"> i </span><span class="pun">}</span><span class="pln"> </span><span class="com">// index is $(elm).index()</span></code></pre>
</div>
</div>

有一个比这个更好的答案

我推荐使用 getAttributeNames()getAttribute(name)作者: Tim Kindberg,MDN 说它们是“ 是访问 Element.attributes的一种高效的内存和性能替代方案

下面是我的原始和更新的答案,如果他们提供一些好处仍然存在。


使用 Array.from()或扩展操作符 ...

更新: 2015年6月,ECMA-262第6版增加了 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>


Note: The following is the legacy answer. It will still work, but the newer Array.from() method is now preferred. This could now be considered a polyfill to support pre-ES2015 targets.

Use .slice to convert the attributes property to Array

The attributes property of DOM nodes is a NamedNodeMap, which is an Array-like object.

An Array-like object is an object which has a length property and whose property names are enumerated, but otherwise has its own methods and does not inherit from Array.prototype

The slice method can be used to convert Array-like objects to a new Array.

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>

这有帮助吗?

此属性将一个元素的所有属性返回到一个数组中。

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>

为了获取并组织许多元素的属性,我建议创建一个包含所有要循环遍历的元素的数组,然后为每个循环遍历的元素的所有属性创建一个子数组。

这是一个脚本示例,该脚本将循环访问收集的元素并打印出两个属性。这个脚本假设总是有两个属性,但是您可以通过进一步的映射轻松地修复这个问题。

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>

如果需要在数组中返回的对象中获取具有名称和值的所有属性,则此方法可以很好地工作。

输出示例:

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

If you want only an array of attribute names for that element, you can just map the results:

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

更简洁的方法: < br/> < br/>

老方法(IE9 +) :

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

ES6方式(边缘12 +) :

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

演示:

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="…"/>

这里的每个答案都缺少使用 GetAttributeNames元素方法的最简单的解决方案!

它以常规 Array 的形式检索元素的所有当前属性的名称,然后您可以将其简化为一个包含键/值的漂亮对象。

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>

试试这个

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

然后得到所有属性

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

用于属性数组

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

<div id="mydiv" a='1' b='2'>...</div> 可以使用

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

假设你有一个如下的 HTML 元素:

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

获得它所有属性的一种方法是将它们转换成一个数组:

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)

下面是您将获得的字符串(来自示例) ,其中包含所有属性:

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

非常简单,只需要遍历属性元素并将它们的 nodeValue 放入一个数组中:

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

对象转换的属性

* 要求: 乐得

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
}

这将把所有 html 属性转换为嵌套对象

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

结果: {custom:{nested:{path1:"value1",path2:"value2"}}}

如果 parseJson 被设置为 true,json 值将被转换为对象

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

Attribute 返回该 HTMLElement 的属性的 NamedNodeMap,这是一个温和的 JavaScript 地图

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

您可以从 NamedNodeMap 创建一个对象,如下所示:

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

然后通过对象属性的点符号访问一个单独的属性:

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