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

Posted

技术标签:

【中文标题】使用 Javascript/jQuery 从 HTML 元素中获取所有属性【英文标题】:Get all Attributes from a HTML element with Javascript/jQuery 【发布时间】:2011-01-04 03:48:00 【问题描述】:

我想将 html 元素中的所有属性放入一个数组中: 就像我有一个 jQuery 对象,它的 html 看起来像这样:

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

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

另一种方法是用 jquery 来实现,但是怎么做呢? 属性的数量和名称是通用的。

谢谢

顺便说一句:我无法使用 document.getelementbyid 或类似的东西访问元素。

【问题讨论】:

【参考方案1】:

非常简单。你只需要遍历 attributes 元素并将它们的 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);

【讨论】:

【参考方案2】:

属性到对象的转换

*需要: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

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

示例 HTML:&lt;div custom-nested-path1="value1" custom-nested-path2="value2"&gt;&lt;/div&gt;

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

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

【讨论】:

【参考方案3】:

假设您有一个如下所示的 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"

【讨论】:

【参考方案4】:
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;
        
    

拥有&lt;div id="mydiv" a='1' b='2'&gt;...&lt;/div&gt; 可以用

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

【讨论】:

【参考方案5】:

试试这样的

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

【讨论】:

【参考方案6】:

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

它将所有元素当前属性的名称作为常规数组检索,然后您可以将其简化为键/值的好对象。

const getAllAttributes = el => el
  .getAttributeNames()
  .reduce((obj, name) => (
    ...obj,
    [name]: el.getAttribute(name)
  ), )

console.log(getAllAttributes(document.querySelector('div')))
&lt;div title="hello" className="foo" data-foo="bar"&gt;&lt;/div&gt;

【讨论】:

注意: 不支持 【参考方案7】:

使用.sliceattributes 属性转换为数组

DOM 节点的attributes 属性是NamedNodeMap,它是一个类数组对象。

类数组对象是具有length 属性且其属性名称已枚举的对象,但除此之外有自己的方法且不继承自Array.prototype

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

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

console.log(attrs);
&lt;span name="test" message="test2"&gt;See console.&lt;/span&gt;

【讨论】:

它将返回对象数组而不是属性名称作为字符串,尽管 OP 没有将名称数组指定为字符串:“我想将 Html 元素中的所有属性放入数组中。”这样做。 好的,有道理 在遍历attrs 中的项目时,您可以使用项目上的name 属性访问属性的名称。 [...elem.attributes]【参考方案8】:

更简洁的方法:

旧方式(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);
document.querySelector() 返回文档中与指定选择器匹配的第一个 Element。 Element.attributes 返回一个 NamedNodeMap 对象,其中包含相应 HTML 元素的分配属性。 [].map() 使用对调用数组中的每个元素调用提供的函数的结果创建一个新数组。

演示:

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

【讨论】:

【参考方案9】:

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

用途:

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

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

【讨论】:

很好,我最喜欢这个答案。非常适合jQuery.attr 两个建议:您可以更新以使用“非缩小”变量名称吗?而且我看到您在 setter 中使用了 jQuery.attr,但在 getter 中使用它也可能是有益的。 另外,小事 - 在你的第一个 for() 语句之后不应该有分号。【参考方案10】:

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

示例输出:

[
    
        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);
&lt;span name="test" message="test2"&gt;&lt;/span&gt;

如果您只需要该元素的属性名称数组,则只需映射结果即可:

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

【讨论】:

【参考方案11】:

这有帮助吗?

此属性为您将元素的所有属性返回到一个数组中。这是一个例子。

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>

【讨论】:

【参考方案12】:

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

插件使用简单的 jQuery 风格调用:

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

您还可以添加第二个字符串参数来获取一个特定的属性。这对于一个元素选择来说并不是真正需要的,因为 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 ereturn"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>

【讨论】:

【参考方案13】:

如果您只想要 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 对象。有没有一种方法可以让我在 jquery 这样的上下文中生成 getelementbyclassname? 你可以使用getElementById - var el = document.getElementById($(myObj).attr("id")); 你可以通过get方法从jQuery对象中获取DOM对象...例如:var obj = $('#example').get(0); @k0ni - 你可以使用例如var atts = $(myObject)[0].attributes; ? 警告:在 IE 中,这不仅被指定,而且所有可能属性【参考方案14】:

因为在 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();

【讨论】:

这里的错字——第 6 行的 el.get(0) 应该是 elem.get(0)。 根据我刚才的经验,这实际上比这要复杂一些。至少在某些情况下。例如,这将包含一个名为“dataFld”且值为“null”(字符串值)的属性,还是会排除它? 它不适用于动态添加的属性,因为属性和属性并不总是同步。【参考方案15】:

您可以将这个简单的插件用作 $('#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);

【讨论】:

仅供参考:这只公开了选择器的第一个元素。 我测试过,它适用于动态添加的属性(chrome)【参考方案16】:

简单:

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

【讨论】:

Attr.nodeValue 已被弃用,取而代之的是 value,Google Chrome 表示。所以这可能是this.name + ':' + this.value。 The Attr Interface【参考方案17】:

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

【讨论】:

遍历所有 span 元素会太慢

以上是关于使用 Javascript/jQuery 从 HTML 元素中获取所有属性的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 javascript 或 jquery 仅从字符串中获取所有 HTML 标记? [关闭]

如何使用 JavaScript/jQuery 从 HTML 中获取符号的 unicode/hex 表示?

如何使用 javascript/jquery 从 URL 中删除获取变量和文件名?

如何从 .cs 文件 (C#) 调用 JavaScript/jQuery 函数

使用 Javascript/jquery 如何从选定行中的每个单元格获取值

如何使用 JavaScript/jQuery 从 ASP.NET Web 窗体的 GridView 内部同时上传多个文件?