jQuery第一个孩子"这个"

mac*_*ca1 307 javascript jquery css-selectors jquery-selectors

我试图将"this"从点击的跨度传递给jQuery函数,然后jQuery函数可以在该被点击元素的第一个子元素上执行jQuery.似乎无法做对......

<p onclick="toggleSection($(this));"><span class="redClass"></span></p>
Run Code Online (Sandbox Code Playgroud)

使用Javascript:

function toggleSection(element) {
  element.toggleClass("redClass");
}
Run Code Online (Sandbox Code Playgroud)

我如何引用元素的第一个子元素?

Sho*_*og9 469

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

element.find(">:first-child").toggleClass("redClass");
Run Code Online (Sandbox Code Playgroud)

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

element.children(":first").toggleClass("redClass");
Run Code Online (Sandbox Code Playgroud)

  • 我知道这是一个古老的问题/答案,但是从jQuery 1.8开始,在该选择器中没有父项的">"选择器的使用被折旧(例如,">:firstchild").我建议改为使用`element.children(":first-child")`或`element.children().first();` (19认同)
  • 我相信`find()`搜索所有后代,`:first-child`可以匹配每个父元素一个元素.因此,此查询可能会返回多个元素.还是我弄错了? (6认同)
  • @KevinB显然他们决定不再弃用​​它 (3认同)

Jør*_*ode 72

使用带选择器children函数来获取单个第一个子节点::firstelement

element.children(":first").toggleClass("redClass");
Run Code Online (Sandbox Code Playgroud)

  • @Zakos:`TypeError:Object [object HTMLAnchorElement]没有方法'toggleClass' (5认同)

man*_*nta 49

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

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

jQuery方式:

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

本土方式:

  1. JavaScript原生' ele.firstChild- 4,934,323 ops/sec(以上所有方法相比都慢了100%firstChild)
  2. 来自jQery的原生DOM ele:notif[0].firstChild- 4,913,658 ops/sec

因此,不建议使用前3个jQuery方法,至少对于第一个孩子来说(我怀疑其他许多情况也是如此).如果你有一个jQuery对象并且需要获取first-child,那么使用数组引用(推荐)从jQuery对象获取本机DOM元素,或者使用.这提供了与常规JavaScript使用相同的结果.[0] .get(0)ele.firstChild

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

  • 实际上,`firstChild`不会给出与jQuery的`children()`或者selector查询相同的结果.`firstChild`将包含很少需要的文本节点.jQuery的`contents()`function*将*包含它们,但`children()`不会.较新的浏览器支持`firstElementChild`,它将提供第一个子元素,但IE <9不支持它.因此,如果使用`firstChild`,则必须手动查找第一个非文本节点子节点. (20认同)
  • 对于预期的行为,`$(":first-child", notif)` 应该是 `$(":first", notif)`。前者将返回所有第一个子元素后代。 (2认同)

Bis*_*del 13

element.children().first();
Run Code Online (Sandbox Code Playgroud)

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

  • 迄今为止最简单的方法,比 `.children(':first')` 更有效。 (3认同)
  • 它的效率如何?它似乎得到了所有的孩子,然后是第一个孩子,而不是第一个孩子. (3认同)
  • @AnthonyMcGrath /sf/answers/1032995071/ (2认同)

the*_*eIV 9

你有没有尝试过

$(":first-child", element).toggleClass("redClass");
Run Code Online (Sandbox Code Playgroud)

我想你想把你的元素设置为搜索的上下文.可能有一个更好的方法来做到这一点,其他一些jQuery大师将跳进这里扔掉你:)

  • 如果`element`有了孙子,这将失败 (3认同)

Yuk*_*élé 6

你可以使用 DOM

$(this).children().first()
// is equivalent to
$(this.firstChild)
Run Code Online (Sandbox Code Playgroud)


Aln*_*tak 5

我刚刚编写了一个插件,.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);
Run Code Online (Sandbox Code Playgroud)

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