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

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

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

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

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

谢谢

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

【问题讨论】:

    标签: javascript jquery attributes parsing


    【解决方案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);
              

              演示:

              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 Boumananswer 是最好的、简单的香草方式。我注意到一些对 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 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>

                    【讨论】:

                      【解决方案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.valueThe 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 元素会太慢
                      猜你喜欢
                      • 2013-01-16
                      • 2020-08-24
                      • 2021-04-17
                      • 1970-01-01
                      • 2018-01-07
                      • 1970-01-01
                      • 2020-04-11
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多