Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么$(div#id)比$(id)慢?_Javascript_Jquery_Performance_Google Chrome - Fatal编程技术网

Javascript 为什么$(div#id)比$(id)慢?

Javascript 为什么$(div#id)比$(id)慢?,javascript,jquery,performance,google-chrome,Javascript,Jquery,Performance,Google Chrome,除非我的测试出了什么问题,否则当我在Chrome上运行这个JSFIDLE时,$(“#id”)选择器大约需要11ms,而$(div#id)选择器大约需要56ms $(document).ready(function(){ startTime = new Date().getTime(); for (i = 0; i < 10000; i++) { s = $("#idC12"); } $("#idResults")

除非我的测试出了什么问题,否则当我在Chrome上运行这个JSFIDLE时,
$(“#id”)
选择器大约需要11ms,而
$(div#id)
选择器大约需要56ms

$(document).ready(function(){
    startTime = new Date().getTime();
    for (i = 0; i < 10000; i++)
    {
        s = $("#idC12");
    }           
    $("#idResults").html("c12 by id only time: "+elapsedMilliseconds(startTime));

    startTime = new Date().getTime();
    for (i = 0; i < 10000; i++)
    {
        s = $("div#idC12");
    }           
    $("#classResults").html("c12 by tagname#id: "+elapsedMilliseconds(startTime));
});

function elapsedMilliseconds(startTime)
{
    var n = new Date();
    var s = n.getTime();
    var diff = s - startTime;
    return diff;
}
$(文档).ready(函数(){
startTime=新日期().getTime();
对于(i=0;i<10000;i++)
{
s=$(“#idC12”);
}           
$(“#idResults”).html(“仅id时间的c12:+elapsedmillyses(startTime));
startTime=新日期().getTime();
对于(i=0;i<10000;i++)
{
s=$(“div#idC12”);
}           
$(“#classResults”).html(“c12按标记名#id:+elapsedmillesons(startTime));
});
函数elapsedMilliseconds(开始时间)
{
var n=新日期();
var s=n.getTime();
var diff=s-开始时间;
返回差;
}

这是因为
$(“#id”)
在内部使用本机函数,该函数使用从id到具有此id的(唯一)元素的映射链接

以下是jQuery源代码中的相关代码:

        // Easily-parseable/retrievable ID or TAG or CLASS selectors
        rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/
        ...
        // Speed-up: Sizzle("#ID")
        if ( (m = match[1]) ) {
            if ( nodeType === 9 ) {
                elem = context.getElementById( m );
                // Check parentNode to catch when Blackberry 4.6 returns
                // nodes that are no longer in the document #6963
                if ( elem && elem.parentNode ) {
                    // Handle the case where IE, Opera, and Webkit return items
                    // by name instead of ID
                    if ( elem.id === m ) {
                        results.push( elem );
                        return results;
                    }
                } else {
                    return results;
                }
            } else {
                // Context is not a document
                if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
                    contains( context, elem ) && elem.id === m ) {
                    results.push( elem );
                    return results;
                }
            }
你会注意到:

  • 当正则表达式检测到
    #someId
    表单时使用它
  • 任何提供的上下文都只会添加一个测试,并不能加快测试速度

请注意,在jQuery之外,当定义CSS规则或使用
document.querySelector
时,此规则仍然适用:当您知道id时,没有什么比使用
document.getElementById
更快的了(除了缓存的元素…。

我在源代码中已经有一段时间了,但我知道一些id选择器过去是由
document.getElementById()
处理的,而更复杂的选择器(例如,
标记名#一些id
)必须通过嘶嘶声,最终通过
document.queryselectoral
$('div#id'))
速度较慢,因为它不直接映射到本机的
getElementById()
方法。

使用div#id时,首先选择所有div


当您使用#id时,它会直接进入id表。

准备好,设置好,开始!You win:)要添加到这一点上,$(div#id)必须在div上运行一个额外的选择器。我必须查看sizzle引擎,看看是否首先查找并检查$(#id)以确保div性,但我想象ir首先运行querySelectAll(div),然后检查id。有时我忘记了为什么使用jQuery,然后我看到了其中的一些评论并记住了原因。这是一个黑暗、黑暗的世界……而且,
id
属性在HTML文档中应该是唯一的,如果不是,那么
$(“#id”)
将只返回与该
id
匹配的第一个元素,就像
getElementById()
一样。但是,
$(“*#id”)
将返回所有满足条件的内容。它是否仍然是一个从右到左的实现呢?@jmar777我不这么认为。我认为CSS就是这样工作的,而不是jQuery的选择过程。我发誓我刚读到一些关于这个的东西。也许我错了。我去找找it@jmar777或者,这可能是一种特殊情况,jQuery在字符串中的任何位置查找
#
,然后将调用直接映射到
getElementById
,而不是从右向左传递给
querySelectorAll
?在获取容器中的特定项目之前,是否需要在左侧获取容器…在右侧?可能是在使用组合选择器时,即使用空格/逗号运算符。@Ian我认为线程与
#foo.bar
样式选择器更相关,然后是
.foo#bar
。并且提供的源中的正则表达式与标记名id选择器不匹配。但是,您可能在从右到左的范围内是正确的,仅适用于“组”级别。我想我可能需要在这一点上进一步挖掘…除了下面非常好的答案,我想说,因为你应该在页面上有唯一的Id,没有必要像div#Id那样具体。。。