使用jQuery选择具有数据属性的元素将为其父元素分配一个空ID [英] Using jQuery to select elements with data attributes assigns a null ID to its parent elements

查看:143
本文介绍了使用jQuery选择具有数据属性的元素将为其父元素分配一个空ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这真是太离奇了。如果在滚动事件中使用jQuery的 .find()来查找具有数据属性的子元素,那么滚动页面会重复添加和删除一个ID到父母这些元素。



这很难描述,但是这里有一个可重现的测试用例:



我把它解释为你不能直接传递一个数据属性,但是这个方法必须是过滤包含它的元素本身。这个修复会很简单。这个罪魁祸首:

  .find([data-animation]); 

将它包装在一个jQuery对象中使得这个功能可以工作:

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

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


  • 这不仅仅是 data
  • 与使用类相关,具有id的元素不会受到影响

  • 没有任何关系使用 .each()循环至少

  • 使用<$ c $时可能没有这样的问题c> .children()改为



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



这是一个奇怪的例子,空id在 body 上,如果上下文被设置为:

Demo

当第二个参数被忽略时,






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

  var groups = $('。group'); 

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

函数showGroup(){

groups.each(函数(){

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


This is truly bizarre. If I use jQuery's .find() to find child elements that have data attributes during a scroll event, then scrolling the page will repeatedly add and remove an ID to the parents of those elements.

It's difficult to describe, but here's a reproducible test case: 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>

Make sure the preview is small enough that there's space to scroll, then inspect one of the "test" elements and scroll up and down. You'll see that in Firefox, it adds and removes an ID of null to the test elements as you scroll:

In Safari, it happens less consistently – but when it does, the ID will start with sizzle.

If I change the .find("[data-animation]") to .find(".test"), it doesn't happen.

Given the sizzle ID that sometimes appears in Safari, I'm guessing this is due to an error in Sizzle (jQuery's selector engine) itself, and not something I'm doing incorrectly in my own code?

解决方案

It seems that the creation of those empty identifiers is something that happens on Firefox only. But all browsers I checked with appear to have something similar going on, be it less visible. With Chrome and Opera you can see an active change on the parent div, without any final effect as a result. With IE it's very subtle, nothing is really noticeable in the DOM tree but there is still a light flicker in the style window. Indicating that it is responding to the same thing as well.

When I dug around a bit these quotes from the jQuery documentation about the arguments that can be passed to the .find() method seemed to hold the best clue :

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/

I interpreted this as that you can't directly pass a data attribute but instead the approach would have to be to filter the elements themselves that contain it. The fix would then be quite simple. The culprite :

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

And wrapping it in a jQuery object makes the functionality work :

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

That actually solved the issue but the assumption was incorrect. Using a data attribute should qualify as a selector expression. The OP should feel free to accept another answer if that can provide a full explanation for the effect this query has on the parent. So far I have only noticed the following :

  • It is not just an issue with data but occurs with all attributes
  • Related to using classes, an element with an id does not get affected
  • Does not have anything to do with using the .each() loop at least
  • Probably the oddest... there is no such issue when using .children() instead

That last one is quite baffling since both methods are very similar. But scouring the documentation I did find a difference, only .find() has a selector context and this looks to be at the root of it.

Here is a strange example where the null id appears on body if the context is set to that :

Demo

And it disappears altogether when the second parameter is omitted...


A working example of the original code, including some other minor tweaks :

Pen

var groups = $('.group');

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

function showGroup() {

  groups.each(function() {

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

这篇关于使用jQuery选择具有数据属性的元素将为其父元素分配一个空ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆