使用具有数据属性的 jQuery 到 select 元素会为其父元素分配一个空 ID

Using jQuery to select elements with data attributes assigns a null ID to its parent elements

这真的很奇怪。如果我在滚动事件中使用 jQuery 的 .find() 查找具有数据属性的子元素,则滚动页面将重复添加和删除 ID 到 parents 这些元素。

很难描述,但这里有一个可重现的测试用例:http://jsfiddle.net/8fouvx9p/

var groups = $(".group");

$(window).bind("scroll resize orientationchange", function() {
  showGroup();   
});
               
function showGroup() {
  $(groups).each(function() {
    var group = $(this),
        elements = $(group).find("[data-animation]");
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>
<div class="group">
    <div data-animation="test" class="test">Test</div>
    <p data-animation="test" class="test">Test</p>
    <span data-animation="test" class="test">Test</span>
</div>

确保预览足够小以便 space 可以滚动,然后检查 "test" 元素之一并上下滚动。您会看到,在 Firefox 中,它会在您滚动时向测试元素添加和删除 ID null

在 Safari 中,它的发生不太一致——但当它发生时,ID 将以 sizzle 开头。

如果我将 .find("[data-animation]") 更改为 .find(".test"),它不会发生。

考虑到 sizzle ID 有时会出现在 Safari 中,我猜这是由于 Sizzle(jQuery 的选择器引擎)本身的错误,而不是我的原因我自己的代码做错了吗?

这些空标识符的创建似乎只发生在 Firefox 上。但是我检查过的所有浏览器似乎都有类似的事情发生,只是不太明显。使用 Chrome 和 Opera,您可以在父 div 上看到一个活跃的变化,结果没有任何最终效果。对于 IE,它非常微妙,在 DOM 树中没有什么是真正值得注意的,但样式 window 中仍然有轻微的闪烁。表示它也在响应同样的事情。

当我仔细研究时,jQuery 文档中关于可以传递给 .find() 方法的参数的引述似乎提供了最好的线索:

A string containing a selector expression to match elements against.

An element or a jQuery object to match elements against.

https://api.jquery.com/find/

我将此解释为您不能直接传递数据属性,而是必须采用这种方法来过滤包含它的元素本身。修复将非常简单。罪魁祸首:

.find("[data-animation]");

并将其包装在 jQuery 对象中使功能起作用:

.find($("[data-animation]"));

这实际上解决了问题,但假设不正确。使用数据属性应该符合选择器表达式的条件。如果可以提供此查询对父级的影响的完整解释,OP 应该随时接受另一个答案。到目前为止,我只注意到以下内容:

  • 这不仅是 data 的问题,而且所有属性都会出现
  • 与使用相关类,具有 id 的元素不受影响
  • 至少与使用 .each() 循环没有任何关系
  • 可能是最奇怪的...使用 .children() 时没有这样的问题

最后一个非常令人费解,因为这两种方法非常相似。但是搜索文档我确实发现了不同之处,只有 .find() 有一个 selector context,这看起来是它的根源。

这是一个奇怪的例子,如果上下文设置为 body 上出现 null id :

Demo

当省略第二个参数时,它会完全消失...


原始代码的工作示例,包括一些其他小的调整:

Pen

var groups = $('.group');

$(window).on('scroll resize orientationchange', showGroup);

function showGroup() {

  groups.each(function() {

    var group = $(this),
    elements = group.find($('[data-animation]'));
  });
}