【问题标题】:jQuery how to find an element based on a data-attribute value?jQuery如何根据数据属性值查找元素?
【发布时间】:2022-01-25 10:39:05
【问题描述】:

我有以下场景:

var el = 'li';

页面上有5个<li>,每个都有data-slide=number属性(数字分别为1,2,3,4,5)

我现在需要找到映射到var current = $('ul').data(current); 并在每次幻灯片更改时更新的当前活动幻灯片编号。

到目前为止,我的尝试都没有成功,试图构建与当前幻灯片匹配的选择器:

$('ul').find(el+[data-slide=+current+]);

不匹配/返回任何东西……

我无法对li 部分进行硬编码的原因是这是一个用户可访问的变量,如果需要,可以将其更改为不同的元素,因此它可能并不总是li

关于我缺少什么的任何想法?

【问题讨论】:

  • 您确定在您的.find(el+[data-slide=+current+]); 中是您编写的代码吗?看来你错过了"[data-slide]"的一些报价
  • 这就是帮助我选择 all 数据属性(无论值)的原因:$('*[data-slide]') 您可以将它与例如$('*[data-slide]').each( function() { ... });

标签: jquery jquery-selectors custom-data-attribute


【解决方案1】:

您必须将current 的值注入Attribute Equals 选择器:

$("ul").find(`[data-slide='${current}']`)

对于较旧的 JavaScript 环境(ES5 及更早版本):

$("ul").find("[data-slide='" + current + "']"); 

【讨论】:

  • 我担心如果数据是通过 jQuery .data(...) 函数添加的,这将不起作用,因为这并不总是呈现属性并且某些时间使用浏览器特定的存储机制。我希望 jQuery 核心有一个特定于数据的选择器的另一个原因。
  • 请注意,它不适用于使用 $('#element').data('some-att-name', value); 设置数据的元素。但仅适用于具有硬编码属性的人。我遇到了这个问题,并通过直接编写属性使其工作集数据 $('#element').attr('data-some-att-name', value);
【解决方案2】:

没有 JQuery,ES6

document.querySelectorAll(`[data-slide='${current}']`);

我知道这个问题是关于 JQuery 的,但是读者可能想要一个纯 JS 方法。

【讨论】:

    【解决方案3】:
    $("ul").find("li[data-slide='" + current + "']");
    

    我希望这可能会更好

    谢谢

    【讨论】:

      【解决方案4】:

      此选择器$("ul [data-slide='" + current +"']"); 将适用于以下结构:

      <ul><li data-slide="item"></li></ul>  
      

      虽然此$("ul[data-slide='" + current +"']"); 适用于:

      &lt;ul data-slide="item"&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt;

      【讨论】:

        【解决方案5】:

        我将 psycho brm's filterByData extension 改进为 jQuery。

        在前一个扩展搜索键值对的情况下,使用此扩展,您可以额外搜索数据属性的存在,而不管其值如何。

        (function ($) {
        
            $.fn.filterByData = function (prop, val) {
                var $self = this;
                if (typeof val === 'undefined') {
                    return $self.filter(
                        function () { return typeof $(this).data(prop) !== 'undefined'; }
                    );
                }
                return $self.filter(
                    function () { return $(this).data(prop) == val; }
                );
            };
        
        })(window.jQuery);
        

        用法:

        $('<b>').data('x', 1).filterByData('x', 1).length    // output: 1
        $('<b>').data('x', 1).filterByData('x').length       // output: 1
        

        // test data
        function extractData() {
          log('data-prop=val ...... ' + $('div').filterByData('prop', 'val').length);
          log('data-prop .......... ' + $('div').filterByData('prop').length);
          log('data-random ........ ' + $('div').filterByData('random').length);
          log('data-test .......... ' + $('div').filterByData('test').length);
          log('data-test=anyval ... ' + $('div').filterByData('test', 'anyval').length);
        }
        
        $(document).ready(function() {
          $('#b5').data('test', 'anyval');
        });
        
        // the actual extension
        (function($) {
        
          $.fn.filterByData = function(prop, val) {
            var $self = this;
            if (typeof val === 'undefined') {
              return $self.filter(
        
                function() {
                  return typeof $(this).data(prop) !== 'undefined';
                });
            }
            return $self.filter(
        
              function() {
                return $(this).data(prop) == val;
              });
          };
        
        })(window.jQuery);
        
        
        //just to quickly log
        function log(txt) {
          if (window.console && console.log) {
            console.log(txt);
            //} else {
            //  alert('You need a console to check the results');
          }
          $("#result").append(txt + "<br />");
        }
        #bPratik {
          font-family: monospace;
        }
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        
        <div id="bPratik">
          <h2>Setup</h2>
          <div id="b1" data-prop="val">Data added inline :: data-prop="val"</div>
          <div id="b2" data-prop="val">Data added inline :: data-prop="val"</div>
          <div id="b3" data-prop="diffval">Data added inline :: data-prop="diffval"</div>
          <div id="b4" data-test="val">Data added inline :: data-test="val"</div>
          <div id="b5">Data will be added via jQuery</div>
          <h2>Output</h2>
          <div id="result"></div>
        
          <hr />
          <button onclick="extractData()">Reveal</button>
        </div>

        或者小提琴:http://jsfiddle.net/PTqmE/46/

        【讨论】:

          【解决方案6】:

          我在使用 jQuery 和 data-* 属性获取元素时遇到了同样的问题。

          所以最短的代码在这里供您参考:

          这是我的 HTML 代码:

          <section data-js="carousel"></section>
          <section></section>
          <section></section>
          <section data-js="carousel"></section>
          

          这是我的 jQuery 选择器:

          $('section[data-js="carousel"]');
          // this will return array of the section elements which has data-js="carousel" attribute.
          

          【讨论】:

            【解决方案7】:

            使用 [data-x=...] 搜索时,请注意,它不适用于 jQuery.data(..) setter

            $('<b data-x="1">'  ).is('[data-x=1]') // this works
            > true
            
            $('<b>').data('x', 1).is('[data-x=1]') // this doesn't
            > false
            
            $('<b>').attr('data-x', 1).is('[data-x=1]') // this is the workaround
            > true
            

            您可以改用这个:

            $.fn.filterByData = function(prop, val) {
                return this.filter(
                    function() { return $(this).data(prop)==val; }
                );
            }
            
            $('<b>').data('x', 1).filterByData('x', 1).length
            > 1
            

            【讨论】:

              【解决方案8】:

              回到他最初的问题,关于如何在事先不知道元素类型的情况下进行这项工作,以下是这样做的:

              $(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");
              

              【讨论】:

                【解决方案9】:

                如果您不想输入所有内容,这里有一个通过数据属性查询的更短的方法:

                $("ul[data-slide='" + current +"']");
                

                仅供参考: http://james.padolsey.com/javascript/a-better-data-selector-for-jquery/

                【讨论】:

                • 对于那些关心的人,鉴于结构&lt;ul&gt;&lt;li data-slide="item"&gt;&lt;/li&gt;&lt;/ul&gt;,此答案的选择器将返回未定义,因此在用户的情况下它不起作用。这个答案将适用于结构&lt;ul data-slide="item"&gt;&lt;li&gt;&lt;/li&gt;&lt;/ul&gt; 虽然我理解为什么它由于简洁而流行,但从技术上讲它是一个不正确的答案。 jsfiddle.net/py5p2abL/1
                • 在 ul 和括号之间放一个空格就可以了。
                猜你喜欢
                • 2011-05-11
                • 1970-01-01
                • 1970-01-01
                • 2014-03-12
                • 2016-11-08
                • 2023-03-29
                相关资源
                最近更新 更多