jQuery的“ this”的第一个孩子


317

我试图将“ this”从单击的范围传递到jQuery函数,然后可以在该单击的元素的第一个孩子上执行jQuery。似乎无法正确处理...

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

Javascript:

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

如何引用element的:first-child?


4
如果您使用的是jQuery,为什么不同时使用jQuery绑定事件处理程序呢?
Vivin Paliath '02

2
因为绑定事件处理程序必须在document.ready()中初始化,这会增加性能影响(这是IE6的应用程序)。还是有另一种方法?
macca1 2010年

嗯..不确定。使用jQuery进行绑定是标准方式(如果您已经在使用jQuery)。使用时,您遇到什么样的性能提升jQuery(document).ready(...)
Vivin Paliath '02

这是一个拥有7个以上开发人员的大型应用程序。最初是4秒钟,之后我才尝试对其进行清理。因此,我宁愿避免在不需要时添加更多内容:)
macca1 2010年

Answers:


482

如果要将选择器应用于现有jQuery集提供的上下文,请尝试使用find()函数

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

JørnSchou-Rode指出,您可能只想查找context元素的第一个直接后代,因此需要选择子选择器(>)。他还指出,您也可以使用children()函数,该函数与find()非常相似,但只搜索层次结构中的一个级别(这是您需要的全部...):

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

1
谢谢!完美地工作。我想下面列出的其他方式也会起作用。
macca1 2010年

6
我相信可以find()搜索所有后代,并且:first-child每个父项可以匹配一个元素。因此,此查询可能会返回几个元素。还是我弄错了?
约恩·舒德罗德(JørnSchou-Rode)2010年

19
我知道这是一个古老的问题/答案,但是从jQuery 1.8开始,在该选择器中没有父级的“>”选择器的使用率已降低(例如“>:firstchild”)。我建议,而不是使用element.children(":first-child")element.children().first();
凯文乙

3
@KevinB显然他们决定完全不要弃用它
Alnitak

1
最好的方法是不要迭代所有项目,然后选择第一个项目,如此处建议的那样。这是坏的。
VSYNC


51

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

给定 notif = $('#foo')

jQuery方式:

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

本机方式:

  1. JavaScript native'ele.firstChild - 4,934,323 ops / sec(所有上述方法比慢100%firstChild
  2. 从jQery本地DOM ELE:notif[0].firstChild- 4913658个操作/秒

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

所有测试均在Chrome Canary build v15.0.854.0中完成


20
实际上,firstChild不会给出与jQuery children()或选择器查询相同的结果。firstChild将包含很少需要的文本节点。jQuery的contents()功能 包括它们,但children()不会。较新的浏览器支持firstElementChild提供第一个子元素,但IE <9不支持它。因此,如果使用,则firstChild必须手动找到第一个非文本节点子级。
最多

1
$(":first-child", notif)应该是$(":first", notif)预期的行为。前者将返回所有第一个孩子元素的后代。
Drazen Bjelovuk


9

你有没有尝试过

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

我认为您想将元素设置为搜索的上下文。可能有更好的方法来执行此操作,其他jQuery专家会跳到这里扔给您:)


3
如果element
孙子,

4

我刚刚编写了一个插件,该插件.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测试中,它比任何其他基于jQuery选择器的方法快几个数量级。


1
我喜欢这个插件-但是有2个问题:1)由于document.body尚未初始化,插件脚本无法包含在头部,2)如果子节点的数量非常多,性能仅比替代方案好得多。对于只有几个孩子(例如少于10个),$('>:first-child',context)速度会更快一些。仅孩子的数量会影响演奏,而不影响深度。
codefactor

有关@codefactor的要点,document.body我会研究一下。
Alnitak

4

您可以使用DOM

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


1

请像这样首先使用它,给类名称加上标签,例如“ myp”

然后使用以下代码

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

-3

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

    $(element).first();

如果要从元素中获取dom中的特定第一个元素,请在下面使用

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

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


11
这是错误的-如果element是DOM节点,则$(element).first()等于$(element),而不是其第一个子节点。
Alnitak

1
同意,如果element是DOM节点$(element).first()等同于$(element),则这会导致我敲除
JS
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.