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

这真是奇怪。 如果我使用jQuery的.find()来查找在滚动事件期间具有数据属性的子元素,那么滚动页面将重复地向这些元素的元素添加和删除ID。

这很难描述,但这是一个可重现的测试用例: 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]"); }); } 
  
Test

Test

Test
Test

Test

Test
Test

Test

Test
Test

Test

Test
Test

Test

Test
Test

Test

Test
Test

Test

Test
Test

Test

Test
Test

Test

Test

确保预览足够小,以便有空间滚动,然后检查其中一个“测试”元素并向上和向下滚动。 您将在Firefox中看到,在滚动时,它会向测试元素添加并删除null的ID:

null ID

在Safari中,它不那么一致 – 但是当它发生时,ID将以sizzle开始。

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

鉴于Safari中有时会出现sizzle ID,我猜这是由于Sizzle(jQuery的选择器引擎)本身出错,而不是我在自己的代码中做错了什么?

似乎这些空标识符的创建仅在Firefox上发生。 但我检查过的所有浏览器似乎都有类似的东西,不太可见。 使用Chrome和Opera,您可以看到父div上的活动更改,因此不会产生任何最终效果。 使用IE它非常微妙,在DOM树中没有什么是真正引人注目的,但在样式窗口中仍然有一个轻微的闪烁。 表明它也在回应同样的事情。

当我挖掘jQuery文档中有关可以传递给.find()方法的参数的这些引用时,似乎掌握了最好的线索:

包含与元素匹配的选择器表达式的字符串。

用于匹配元素的元素或jQuery对象。

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

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

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

并将其包装在jQuery对象中使function工作:

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

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

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

最后一个是非常令人困惑的,因为两种方法非常相似。 但是在搜索文档时我发现了一个区别,只有.find()有一个选择器上下文 ,这看起来就是它的根源。

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

演示

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


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

钢笔

 var groups = $('.group'); $(window).on('scroll resize orientationchange', showGroup); function showGroup() { groups.each(function() { var group = $(this), elements = group.find($('[data-animation]')); }); }