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

时间:2022-06-23 20:45:40

I have seen plenty of discussion regarding the fastest way to select a first child element using jQuery. As can be expected, the native DOM firstChild property is much faster than using a jQuery selector or combination of selectors -- see http://jsperf.com/jquery-first-child-selection-performance/6. This is not usually a problem -- either it's being used in a place where performance is not a big deal, or it's easy enough to just access the DOM element and use its .firstChild property. However, there are a couple problems with this:

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

  • firstChild could return a text or comment node, rather than an element, as a jQuery selector would return
  • firstChild可以返回一个文本或注释节点,而不是一个元素,因为jQuery选择器将返回

  • If I need to select the first child of multiple elements, I must either use a slow selector, or go to a lot of extra work iterating over DOM elements, adding them to a collection, then putting them back into a jQuery object.
  • 如果我需要选择多个元素的第一个子元素,我必须使用慢速选择器,或者进行大量额外的工作迭代DOM元素,将它们添加到集合中,然后将它们放回到jQuery对象中。

It seems to me that the cost of adding a firstChild method to the core jQuery library would be far smaller than the benefits. I took my own shot at creating such a method for my own use:

在我看来,将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);
};

In the tests I created at http://jsperf.com/jquery-multiple-first-child-selection, this function performs more than five times faster than any other option. The tests are based on the tests mentioned above, but are selecting the first children of multiple elements, rather than a single element.

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

Is there something I am missing? A technique that I should be using? Or is this an issue than one should never worry about? Is there a reason to not include a function like this in jQuery?

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

2 个解决方案

#1


12  

"Why does jQuery not provide a .firstChild method?"

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

Feature creep, most likely.

特征是蠕变,最有可能。

It can be accomplished with other methods as you stated, and if performance is a concern, you can extend jQuery for that specific need as you've done.

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


You can improve performance in your code a little more...

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

$.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);
};

#2


0  

For the single element cases you can use the

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

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

which seems to almost match yours in speed..

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

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

#1


12  

"Why does jQuery not provide a .firstChild method?"

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

Feature creep, most likely.

特征是蠕变,最有可能。

It can be accomplished with other methods as you stated, and if performance is a concern, you can extend jQuery for that specific need as you've done.

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


You can improve performance in your code a little more...

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

$.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);
};

#2


0  

For the single element cases you can use the

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

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

which seems to almost match yours in speed..

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

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