jQuery UI: data选择器无法返回HTML5数据属性

5

假设我有这样一段HTML代码:

<div id="container">
   <ul>
       <li><a href="#" data-some-info="foo">Bar</a>
       <!-- repeating a few like the one -->                          -->
       <!-- above for a while ...        -->
   </uL>
</div>

当定义了data some-info时,我希望将某些内容应用到所有锚点元素上。

我只是想了解为什么会出现这种行为(这是一个bug吗?)

$("#container").find("a:data(some-info)").size();  // -> 0
$("#container").find("a").data("some-info");       // -> "foo"
$("#container").find("a:data(some-info)").size();  // -> 1 (actual expected val)

有什么想法吗?

更多信息:我正在使用jQuery 1.9.0和jQuery UI 1.9.2

** 编辑 **

知道关于$("#container").find("a[data-some-info]")。这不是我在这里质疑的问题。如果有一个数据选择器,为什么它会表现出这种方式?


1
是否有关于 :data 选择器的可用文档?我猜它是一个 jQuery 的 css 选择器,只查看已经被缓存的元素数据(这至少可以解释你所看到的行为)。 - Kevin B
啊,这是由jQuery UI添加的。注意文档根本没有提到它可以通过数据属性选择。 - Kevin B
@KevinB,你可能有点眉目了。 - Yanick Rochon
3个回答

3
这是选择器的实现方式:
$.extend( $.expr[ ":" ], {
    data: $.expr.createPseudo ?
        $.expr.createPseudo(function( dataName ) {
            return function( elem ) {
                return !!$.data( elem, dataName );
            };
        }) :
        // support: jQuery <1.8
        function( elem, i, match ) {
            return !!$.data( elem, match[ 3 ] );
        },

(Note: See https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.core.js#L160 for reference.)
请注意它使用的是$.data而不是$(elem).data。这意味着它只查找通过$.data$().data方法存储在元素上的数据,而不是查找元素上的数据属性,我认为它也不是为此而设计的。您应该使用属性等于选择器[data-foo]。但要注意,它只查看属性,如果您使用jQuery的$().data将数据添加到元素中,则可能无法匹配该选择器,因为jQuery不会更新属性。

1

来自文档,

表达式$( "div:data(foo)")匹配一个<div>,如果它存储了通过.data( "foo", value )存储的数据。

而来自jQuery代码 ->

jQuery data() 存储在对象的内部数据缓存中的单独对象中,以避免内部数据和用户定义数据之间的键冲突(来自jQuery代码的注释)。

https://github.com/jquery/jquery/blob/master/src/data.js#L51

https://github.com/jquery/jquery/blob/master/src/data.js#L63

当在HTML中定义时,它只是一个用户定义的数据元素,不会被jQuery的:data选择器选中。
但是,当您调用.data(some-info)时,它实际上读取用户定义的数据并将其复制到内部数据中,并且稍后使用:data选取器拾取元素,因为它可以在内部数据中找到它。
这不是一个错误,因为文档中明确提到了这一点。
你应该使用.length属性来获取选择器返回的元素数量。
另外,.size已经自jQuery 1.8起被弃用。http://api.jquery.com/size/

length或者size都可以,它们并没有任何区别。但是我会记住用size这个词 :) - Yanick Rochon
这不是一个错误,但显然是一种意外的行为,因为当您调用.data(some-info)时,用户数据会被返回。 - maurocchi

1
:data选择器不是jQuery核心的一部分。这可能是一个错误,但是jQuery文档说HTML5数据属性被拉入内部jQuery数据对象(大概是在调用.data时),而不是作为:data伪选择器的一部分可用(根据jQuery UI文档,:data查询内部数据表示“原样”,并且与HTML5数据属性无关)。
备选方案:
使用$("#container").find("a[data-some-info='foo']"),或者如果数据属性上设置了任何内容,则使用.find("a[data-some-info]")。

不,我在问为什么data selector会表现出这种行为。 - Yanick Rochon
到目前为止,你似乎有了正确的答案。...看起来在所有情况下都是未定义行为(文档不太完善)。 - Yanick Rochon
我建议向JQuery UI的开发人员提出一个修复建议,使:data选择器更像对.data的调用,但出于性能原因可能会这样。我认为使用情况是选择由先前对.data(key, val)的调用设置的混合CSS和内部存储的内容。 - Plynx

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