在jQuery中选择后代元素的最快方法是什么?


101

据我所知,有许多方法可以选择jQuery中的子元素。

//Store parent in a variable  
var $parent = $("#parent");

方法1 (通过使用范围)

$(".child", $parent).show();

方法2 (find()方法)

$parent.find(".child").show();

方法3 (仅对于直系儿童)

$parent.children(".child").show();

方法4 (通过CSS选择器) -@spinon建议

$("#parent > .child").show();

方法5 (与方法2相同) -根据@Kai

$("#parent .child").show();

我不熟悉能够自己进行调查的配置文件,因此,我很想看看您必须说些什么。

附言:我知道这可能是这个问题的重复,但并未涵盖所有方法。


此外,@ spinon-仅适用于直系儿童吗?CSS规范说:“匹配任何作为元素E的子元素的F元素。”
Marko 2010年

7
您真的不必担心哪个会更快(除非您要进行很大的dom操作)... jQuery的构建速度非常快……
Reigel 2010年

我有一个2MB的HTML文件,不要问如何或为什么:)
Marko 2010年

1
是。仅一级后代。
人造纤维

还有另一种方法。$(“#parent .child”)。show(); 与#2相同。:)

Answers:


95

方法1方法2相同,唯一的区别是方法1需要解析传递的范围并将其转换为对的调用$parent.find(".child").show();

方法4方法5都需要解析选择器,然后分别调用:$('#parent').children().filter('.child')$('#parent').filter('.child')

因此,方法3总是最快的,因为它需要做的工作量最少,并且使用最直接的方法来获得一级孩子。

基于此处的Anurag修订的速度测试:http : //jsfiddle.net/QLV9y/1/

速度测试:(越多越好)

Chrome上,方法3是最好的方法,然后是方法1/2和4/5

在此处输入图片说明

Firefox上,方法3最好还是方法1/2最好是4/5

在此处输入图片说明

Opera上,方法3仍然是最佳方法,然后是方法4/5然后是1/2

在此处输入图片说明

IE 8上,虽然总体上比其他浏览器要慢,但它仍然遵循方法3、1、2、4、5的顺序。

在此处输入图片说明

总体而言,方法3是直接使用的最佳方法,因为方法3不需要遍历一个以上级别的子元素(与方法1/2不同),并且不需要像方法4/5那样进行解析

不过,请记住,在其中一些方法中,我们将苹果与橙子进行比较,因为方法5着眼于所有孩子,而不是头等孩子。


相同,是指它们都使用相同的逻辑进行搜索?
Marko 2010年

4
您不是说方法1和2相同吗?
Guffa

感谢@Aaron-我想看看其他人的想法,如果每个人都同意,我会接受您的回答。干杯:)
马可(Marko)2010年

@JP,我的意思是,需要花费一些时间才能识别出正在传递作用域以将其转换为$parent.find(".child");命令。
亚伦·哈伦

2
@Aaron @Marko-测试可能有些偏斜,因为我们始终使用根节点作为上下文,并且文档很大。尽管如此,在大多数运行中,我看到1和2在20 ops / sec之内彼此对齐。与1和2相比,4的运行速度要慢100-200运维,而5的运行速度则要慢400运维,这是可以理解的,因为它遍历所有后代,而不仅仅是孩子。图表-tinyurl.com/25p4dhq
阿努拉格2010年

13

方法1

使用jQuery不能再短又快了。此调用直接下降到$(context).find(selector)方法2,由于优化),进而调用getElementById

方法2

这样做是一样的,但是没有一些不必要的内部函数调用。

方法3

using children()比using快find(),但当然children()只能找到根元素的直接子元素,而find()会自上而下地搜索所有子元素(包括子子元素)

方法4

使用这样的选择器,必须慢一些。由于sizzle(这是jQuery的选择器引擎)从右到左起作用,因此它将.child首先匹配所有类,然后再看它们是否是id'parent'的直接子代。

方法5

正确地说$(context).find(selector),由于jQuery函数内的某些优化,此调用也将创建一个调用,否则也可能会经过(slower)sizzle engine


2
您不是在说var $ parent = $(“#parent”)是吗?我看不到元素具有类时方法1如何使用getElementById?
Marko

1
我想同意,但是在方法1中,文档说,- Internally, selector context is implemented with the .find() method请更新,我知道您对OP的标签感到困惑:)
Reigel 2010年

@Reigel:确实修复了该问题。@Marko:解析#parent表示一个id,如果它是一个类,则getElementById显然不会使用。
jAndy

10

由于这是一个古老的职位,所以事情会随着时间而改变。到目前为止,我已经对最新的浏览器版本进行了一些测试,并将其发布在这里是为了避免误解。

在HTML5和CSS3兼容浏览器上使用jQuery 2.1,性能会发生变化。

这是测试方案和结果:

function doTest(selectorCallback) {
    var iterations = 100000;

    // Record the starting time, in UTC milliseconds.
    var start = new Date().getTime();

    for (var i = 0; i < iterations; i++) {
        // Execute the selector. The result does not need to be used or assigned
        selectorCallback();
    }

    // Determine how many milliseconds elapsed and return
    return new Date().getTime() - start;
}

function start() {
    jQuery('#stats').html('Testing...');
    var results = '';

    results += "$('#parent .child'): " + doTest(function() { jQuery('#parent .child'); }) + "ms";
    results += "<br/>$('#parent > .child'): " + doTest(function() { jQuery('#parent > .child'); }) + "ms";
    results += "<br/>$('#parent').children('.child'): " + doTest(function() { jQuery('#parent').children('.child'); }) + "ms";
    results += "<br/>$('#parent').find('.child'): " + doTest(function() { jQuery('#parent').find('.child'); }) + "ms";
    $parent = jQuery('#parent');
    results += "<br/>$parent.find('.child'): " + doTest(function() { $parent.find('.child'); }) + "ms";

    jQuery('#stats').html(results);
}
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=8, IE=9, chrome=1" />
    <title>HTML5 test</title>
    <script src="//code.jquery.com/jquery-2.1.1.js"></script>
</head>
<body>

<div id="stats"></div>
<button onclick="start()">Test</button>

<div>
    <div id="parent">
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
    </div>
</div>

</body>
</html>

因此,对于10万次迭代,我得到:

JS jQuery选择器统计

(出于格式化目的,我将它们添加为img。)

您可以自己运行代码片段进行测试;)


哦! 然后看起来.find()做得很好。继续使用它。:)
安德鲁·苏尔杜
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.