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

und*_*ned 16 performance jquery 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);
};
Run Code Online (Sandbox Code Playgroud)

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

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

小智 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);
};
Run Code Online (Sandbox Code Playgroud)

  • +1,我不知道firstElementChild.好奇的是,我在这里找到了一个浏览器支持图表:http://www.quirksmode.org/dom/w3c_traversal.html (2认同)