“this”的jQuery第一个孩子

Posted

技术标签:

【中文标题】“this”的jQuery第一个孩子【英文标题】:jQuery first child of "this" 【发布时间】:2011-01-17 13:21:28 【问题描述】:

我正在尝试将“this”从单击的范围传递给 jQuery 函数,然后该函数可以在该单击元素的第一个子元素上执行 jQuery。好像没弄好...

<p onclick="toggleSection($(this));"><span class="redClass"></span></p>

javascript

function toggleSection(element) 
  element.toggleClass("redClass");

如何引用元素的 :first-child?

【问题讨论】:

如果你使用 jQuery,为什么不使用 jQuery 绑定事件处理程序呢? 因为绑定事件处理程序必须在 document.ready() 中初始化,这会增加性能(这是 IE6 的应用程序)。还是有其他方法? 嗯..不确定。使用 jQuery 绑定是标准方式(如果您已经在使用 jQuery)。当您使用jQuery(document).ready(...) 时,您遇到了什么样的性能损失? 这是一个拥有 7 个以上开发人员的大型应用程序。在我尝试清理它之前,最初是 4 多秒。所以我宁愿避免在不需要时添加更多内容:) 【参考方案1】:

如果您想将选择器应用于现有 jQuery 集提供的上下文,请尝试 find() function:

element.find(">:first-child").toggleClass("redClass");

Jørn Schou-Rode 指出,您可能只想找到上下文元素的第一个 直接后代,因此是 the child selector (>)。 He also points out,你也可以使用 children() function,它与 find() 非常相似,但只搜索层次结构深处的一层(这就是你所需要的......):

element.children(":first").toggleClass("redClass");

【讨论】:

谢谢!完美运行。我想下面列出的其他方法也可以。 我相信find() 会搜索所有后代,:first-child 可以匹配每个父元素一个元素。因此,此查询可能会返回多个元素。还是我弄错了? 我知道这是一个老问题/答案,但是从 jQuery 1.8 开始,在该选择器中没有父级的 ">" 选择器的使用已被弃用(例如,">:firstchild")。我建议改用element.children(":first-child")element.children().first(); @KevinB 显然他们决定不弃用它 最好的方法不是迭代所有项目,然后选择第一个,正如一些人建议的那样。这会很糟糕。【参考方案2】:

你试过了吗

$(":first-child", element).toggleClass("redClass");

我认为您想将元素设置为搜索的上下文。可能有更好的方法来做到这一点,其他一些 jQuery 大师会跳到这里并扔给你:)

【讨论】:

如果element 有孙子,这将失败【参考方案3】:

使用children function 和:first selector 来获得element单个第一个孩子:

element.children(":first").toggleClass("redClass");

【讨论】:

element.children()[0].toggleClass("redClass"); @Zakos: TypeError: Object [object htmlAnchorElement] has no method 'toggleClass'【参考方案4】:

我添加了jsperf 测试以查看获取第一个孩子(总共 1000 多个孩子)的不同方法的速度差异

给定,notif = $('#foo')

jQuery 方式:

    $(":first-child", notif) - 4,304 ops/sec - 最快 notif.children(":first") - 653 ops/sec - 慢 85% notif.children()[0] - 1,416 操作/秒 - 慢 67%

原生方式:

    JavaScript native' ele.firstChild - 4,934,323 ops/sec(与firstChild相比,上述所有方法都慢了100%) 来自 jQery 的本机 DOM 元素:notif[0].firstChild - 4,913,658 ops/sec

因此,不推荐前 3 种 jQuery 方法,至少对于第一个孩子(我怀疑其他许多方法也是如此)。如果您有一个 jQuery 对象并且需要获取第一个子对象,则 从 jQuery 对象中获取本机 DOM 元素,使用数组引用 [0](推荐).get(0) 并使用 ele.firstChild。这给出了与常规 JavaScript 使用相同的结果。

所有测试都在 Chrome Canary 版本 v15.0.854.0 中完成

【讨论】:

实际上,firstChild 不会给出与 jQuery 的 children() 或选择器查询相同的结果。 firstChild 将包含很少需要的文本节点。 jQuery 的 contents() 函数 包含它们,但 children() 不会。较新的浏览器支持firstElementChild,它将给出第一个子元素,但 IE firstChild,则必须手动查找第一个非文本节点子节点。 $(":first-child", notif) 应该是 $(":first", notif) 以获得预期的行为。前者将返回所有第一个子元素的后代。【参考方案5】:

请这样使用 首先给标签 p 一个类名,比如“myp”

然后使用下面的代码

$(document).ready(function() 
    $(".myp").click(function() 
        $(this).children(":first").toggleClass("classname"); // this will access the span.
    )
)

【讨论】:

【参考方案6】:

如果你想要第一个孩子,你需要

    $(element).first();

如果你想从你的元素中获得特定的第一个元素,那么在下面使用

    var spanElement = $(elementId).find(".redClass :first");
    $(spanElement).addClass("yourClassHere");

试试看:http://jsfiddle.net/vgGbc/2/

【讨论】:

这是错误的 - 如果 element 是一个 DOM 节点,那么 $(element).first() 相当于 $(element),而不是它的第一个子节点。 同意,如果元素是 DOM 节点 $(element).first() 是等效的 $(element) 这导致了我与 knockoutJS 绑定的问题【参考方案7】:

我刚刚编写了一个插件,如果可能,它使用.firstElementChild,并在必要时回退到迭代每个单独的节点:

(function ($) 
    var useElementChild = ('firstElementChild' in document.createElement('div'));

    $.fn.firstChild = function () 
        return this.map(function() 
            if (useElementChild) 
                return this.firstElementChild;
             else 
                var node = this.firstChild;
                while (node) 
                    if (node.type === 1) 
                        break;
                    
                    node = node.nextSibling;
                
                return node;
            
        );
    ;
)(jQuery);

它不如纯 DOM 解决方案快,但在 Chrome 24 下的 jsperf tests 中,它比任何其他基于 jQuery 选择器的方法快几个数量级。

【讨论】:

我喜欢这个插件 - 但有两个问题:1) 插件脚本不能包含在头部,因为 document.body 尚未初始化,2) 性能仅比替代方案好得多,如果子节点的数量非常多。对于只有几个孩子(比如少于 10 个),$('&gt;:first-child',context) 会快一点。只有孩子的数量会影响性能,而不是深度。 @codefactor 关于document.body 的好点子——我会调查的。【参考方案8】:

这可以通过如下简单的魔法来完成:

$(":first-child", element).toggleClass("redClass");

参考:http://www.snoopcode.com/jquery/jquery-first-child-selector

【讨论】:

【参考方案9】:
element.children().first();

找到所有孩子并获得第一个。

【讨论】:

目前为止最简单的方法,比.children(':first')效率更高。 如何更高效?似乎它获取所有孩子,然后获取第一个孩子,而不是只获取第一个孩子。 @AnthonyMcGrath ***.com/a/14757072/940098【参考方案10】:

你可以使用 DOM

$(this).children().first()
// is equivalent to
$(this.firstChild)

【讨论】:

以上是关于“this”的jQuery第一个孩子的主要内容,如果未能解决你的问题,请参考以下文章

jQuery each:如果元素是第一个孩子,否则

使用 jQuery 获取第二个孩子

使用 .each() 可调整大小的 jquery ui 仅适用于第一个孩子

如何检查元素是不是不是第一个孩子?

将数据添加到 FlatList 始终显示第一个孩子

反应只重新渲染一个孩子