为什么jQuery不提供.firstChild方法?

时间:2012-04-11 00:34:45

标签: jquery performance jquery-selectors

我已经看到很多关于使用jQuery选择第一个子元素的最快方法的讨论。可以预料,本机DOM firstChild属性比使用jQuery选择器或选择器组合要快得多 - 请参阅http://jsperf.com/jquery-first-child-selection-performance/6。这通常不是问题 - 要么在性能不是很大的地方使用,要么只是访问DOM元素并使用其.firstChild属性就足够了。但是,这有几个问题:

  • firstChild可以返回一个文本或注释节点,而不是一个元素,因为jQuery选择器会返回
  • 如果我需要选择多个元素的第一个子元素,我必须使用慢速选择器,或者进行大量额外的迭代DOM元素的工作,将它们添加到集合中,然后将它们放回到jQuery对象中

在我看来,将firstChild方法添加到核心jQuery库的成本远远小于其好处。我自己动手制作了一个供我自己使用的方法:

$.fn.firstChild = function() {
    var ret = [];

    this.each(function() {
        var el = this.firstChild;

        //the DOM firstChild property could return a text node or comment instead of an element
        while (el && el.nodeType != 1)
            el = el.nextSibling;

        if (el) ret.push(el);
    });

    //maintain jQuery chaining and end() functionality
    return this.pushStack(ret);
};

在我http://jsperf.com/jquery-multiple-first-child-selection创建的测试中,此函数的执行速度比其他任何选项快五倍以上。测试基于上面提到的测试,但是选择多个元素的第一个子元素,而不是单个元素。

我有什么遗失的吗?我应该使用的技术?或者这是一个人们不应该担心的问题?有没有理由不在jQuery中包含这样的函数?

2 个答案:

答案 0 :(得分:12)

  

“为什么jQuery不提供.firstChild方法?”

特征蠕变,很有可能。

可以使用您所说的其他方法来完成,如果性能是一个问题,您可以像您一样扩展jQuery以满足特定需求。


您可以更多地提高代码的性能......

$.fn.firstChild = function () {
    var ret = [];
    // use a for loop
    for (var i = 0, len = this.length; i < len; i++) {
        var this_el = this[i],
            el = this_el.firstElementChild; // try firstElementChild first
        if (!el) {
            el = this_el.firstChild;
            while (el && el.nodeType != 1)
                el = el.nextSibling;
        }
        if (el) ret.push(el);
    }
    //maintain jQuery chaining and end() functionality
    return this.pushStack(ret);
};

答案 1 :(得分:0)

对于单个元素的情况,您可以使用

$('.test > eq(0)')

这似乎与你的速度几乎相匹配..

http://jsperf.com/jquery-multiple-first-child-selection/2