【问题标题】:Grab values of an attribute from all elements in jQuery从jQuery中的所有元素中获取属性值
【发布时间】:2020-08-24 11:38:27
【问题描述】:

假设我们有以下 HTML:

<entries>
  <entry id="1" />
  <entry id="2" />
  <entry id="3" />
  <entry id="4" />
</entries>

jQuery 是否具有用于检索特定属性的所有值的内置机制?如果没有,那么检索它们的最有效方法是什么?

例如,类似于:$('entry').attrs('id'),返回所有元素的值列表,返回类似于["1", "2", "3", "4"]

General Attributes 下的 jQuery 文档(这是找到 attr 的位置)没有给出任何提示存在这样的事情,而且我在 StackOverflow 或任何其他支持论坛上都没有找到任何询问这个问题的信息。

【问题讨论】:

标签: javascript jquery attributes


【解决方案1】:

你可以使用类似的东西:https://jsfiddle.net/g903dyp6/

<entries>
  <entry id="1" />
  <entry id="2" />
  <entry id="3" />
  <entry id="4" />
</entries>

let arr = $.map($('entry'), function(el) {
     return $(el).attr('id');
});

【讨论】:

    【解决方案2】:

    没有直接的功能可以做到这一点。但是,使用.map() 可以轻松完成。例如,

    let ids = $('entry').map(function() {
        return this.getAttribute('id');
    }).get();
    

    let ids = $('entry').map(function() {
        return this.getAttribute('id');
    }).get();
    
    console.log(ids);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <entries>
      <entry id="1" />
      <entry id="2" />
      <entry id="3" />
      <entry id="4" />
    </entries>

    【讨论】:

    • 这个规模如何?假设您有 5,000-10,000 个 entry 标签 - 在这种情况下性能如何?在这种情况下有更好的解决方案吗?
    • @That1Guy 我不确定。 Jsperf 有麻烦了。
    • 仅供参考,而不是将元素包装在 jQuery 对象中以获取属性的值(例如 $(this).attr('id'),您可以简单地执行 this.getAttribute('id')
    【解决方案3】:

    这是使用 JavaScript Array .map() 函数的一种方式:

    let ids = jQuery.makeArray($('entry')).map(entry => entry.id);
    
    console.log('ids:', ids);
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
    <entries>
      <entry id="1" />
      <entry id="2" />
      <entry id="3" />
      <entry id="4" />
    </entries>

    【讨论】:

      【解决方案4】:

      您可以使用 jQuery.fn.extend() 扩展 jQuery 并添加一个自定义方法,该方法迭代所有匹配的元素,从所有元素中提取单个或多个属性,并将它们分别推送/合并到返回的数组/对象中。

      由于实现是 vanilla JS,这将比在所有中间步骤中使用 jQuery 对象和函数更快,但可能需要根据您需要支持的浏览器进行一些调整:

      jQuery.fn.extend({
        attrs: function(attributeName) {
          if (attributeName) {
              return this.toArray().map((el) => el.getAttribute(attributeName));
          }
          
          return this.toArray().reduce((merged, el) => {
            const { attributes } = el;
            const totalAttributes = attributes.length;
      
            for (let i = 0; i < totalAttributes; ++i) {  
              const attribute = attributes[i].nodeName;
      
              if (merged[attribute]) {
                merged[attribute].push(el.getAttribute(attribute));
              } else {
                merged[attribute] = [el.getAttribute(attribute)];
              }
            }
      
            return merged;
          }, {});
        },
      });
      
      console.log($('entry').attrs());
      console.log($('entry').attrs('id'));
      console.log($('entry').attrs('class'));
      .as-console-wrapper {
        max-height: 100% !important;
      }
      <entries>
        <entry id="1" class="foo" />
        <entry id="2" class="bar" />
        <entry id="3" class="baz" />
        <entry id="4" class="qux" />
      </entries>
      
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

      【讨论】:

      • @That1Guy 这可能比在所有中间步骤中使用 jQuery 的解决方案更快、更灵活且可扩展性更好。
      猜你喜欢
      • 2018-01-07
      • 1970-01-01
      • 2011-01-04
      • 2021-08-26
      • 2013-01-16
      • 2011-02-14
      • 2012-01-20
      • 2014-06-09
      • 2015-12-08
      相关资源
      最近更新 更多