jQuery如何根据data属性的值查找元素?

1157

我有以下情况:

var el = 'li';

页面上有5个<li>,每个<li>都有一个data-slide=number属性,其中number分别为1,2,3,4,5

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

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

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

没有匹配/返回任何内容...

我不能硬编码

  • 部分的原因是,这是一个可以由用户访问的变量,如果需要,可以更改为不同的元素,因此它可能并不总是
  • 元素。

    你有什么想法,我错过了什么?


  • 6
    你确定你写的代码是在.find(el+[data-slide=+current+]);里面吗?看起来你漏了一些引号 "[data-slide]" - xandy
    这就是帮助我选择所有数据属性(不考虑值)的方法:$('*[data-slide]') 您可以像这样使用它:$('*[data-slide]').each( function() { ... }); - Avatar
    9个回答

    1729
    你需要将current的值注入到一个属性等于选择器中:
    $("ul").find(`[data-slide='${current}']`)
    

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

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

    86
    我担心如果通过jQuery的.data(...)函数添加数据,这个方法并不总是会渲染出一个属性,并且有时会使用浏览器特定的存储机制,所以可能无法正常工作。另外一个原因是我希望jQuery核心库有一个特定于数据的选择器。 - AaronLS
    89
    请注意,此方法不适用于使用 $('#element').data('some-att-name', value) 来设置数据的元素,只适用于硬编码属性的元素。我遇到了这个问题,为了使其工作,请直接通过写入属性 $('#element').attr('data-some-att-name', value) 来设置数据。 - Pawel
    1
    天啊,我在这里浪费了几个小时!确认使用动态添加数据-{somevalue}属性可以让您使用Jquery选择器查找数据字段。 - Vinnie Amir

    560

    37
    如果您关心的话,针对结构<ul><li data-slide="item"></li></ul>,这个答案的选择器将返回未定义(undefined),因此在用户的情况下无法使用。但是这个答案会适用于结构<ul data-slide="item"><li></li></ul>。虽然我理解它之所以受欢迎是因为简洁,但从技术上讲,这不是正确的答案。http://jsfiddle.net/py5p2abL/1/ - akousmata
    只需在 ul 和括号之间放一个空格,它就可以工作了。 - Artem

    251

    当使用[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
    

    注意,这适用于jQuery.data setter和其他方法。 - Sablefoste

    75

    没有使用JQuery和ES6

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

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


    43
    我改进了 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>

    或者使用 jsfiddle:http://jsfiddle.net/PTqmE/46/


    这似乎是有效的:MyContainerSelector.find('div[data-template-bind]'); - Rodney

    41

    在使用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.
    

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

    我希望这样可能会更有效

    谢谢


    24

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

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

    这个 $("ul[data-slide='" + current +"']"); 适用于以下情况:

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


    15

    回到他最初的问题,即如何在不提前知道元素类型的情况下使其正常工作,以下代码实现了这一点:

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

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接