Javascript 如果您在jQuery中按ID选择一个元素,那么通过给它一个上下文,它的速度还会提高吗?

Javascript 如果您在jQuery中按ID选择一个元素,那么通过给它一个上下文,它的速度还会提高吗?,javascript,jquery,Javascript,Jquery,想象一下这种简化的标记: <div id="header"> <!-- Other things.... --> <div id="detail"> </div> </div> jQuery以这种方式查找详细信息是否存在速度差异: var $detail = $("#detail", $hdr); vs 由于详细信息是通过ID查找的?否,您不必这样做。由于id在文档中是唯一的,因此无需添加任何其他优化 我会和你一

想象一下这种简化的标记:

<div id="header">
   <!-- Other things.... -->
   <div id="detail">

   </div>
</div>
jQuery以这种方式查找详细信息是否存在速度差异:

var $detail = $("#detail", $hdr);
vs


由于详细信息是通过ID查找的?

否,您不必这样做。由于id在文档中是唯一的,因此无需添加任何其他优化

我会和你一起去

var $detail = $("#detail");

不。传递上下文实际上会使它变慢。下面给出了jQuery的相关源代码,并给出了解释

这条代码基本上说:

如果选择器是HTML字符串 或者是一个身份证,或者是 具体来说,HTML或无上下文是 鉴于 1.a然后执行一些操作,比如调用document.getElementById 否则,请计算上下文,然后运行选择器 这是剥离的来源

init: function( selector, context ) {
    ...
    if ( typeof selector === "string" ) {
        ...
        // This gets ignored because we passed a context
        // document.getElementById() isn't called directly
        if ( match && (match[1] || !context) ) {
            ...
            } else {
                elem = document.getElementById( match[2] );
                ...
            }
        ...
        // Either this gets executed if a jQuery wrapped context was passed
        } else if ( !context || context.jquery ) {
            return (context || rootjQuery).find( selector );
        }
        // Or this gets executed, if a simple selector was passed as context
        } else {
            return jQuery( context ).find( selector );
        }
    ...
}
match是正则表达式的结果数组 表达式,以确定选择器 是HTML字符串或id 表示如果是HTML字符串, 然后将填充匹配项[1]。 如果是身份证,那么 将填充匹配项[2]


答案在于如何存储ID。分配的ID保存在类似散列的数据结构中。如果搜索一个完全限定的ID而不是[ID*=foo],那么在没有任何修改器的情况下,所需的定位时间应该是最快的,因为这是一个直接的哈希查找。

而且我看到了可靠的文档,测试表明,当包含范围时,上下文的定位速度较慢,只是目前找不到链接。+1,此外,即使不查看源代码,也可以推断,如果ID选择器进行了远程优化,则速度会变慢,因为添加上下文会添加第二个要检查的条件。不确定在使用ID选择器的情况下添加忽略上下文的简单条件是否会产生任何明显的效果。我想,这样做的一个原因是,它提供了对具有重复ID的元素的访问。我知道这不好也不合法,而且依赖于浏览器等等,但是document.getElementById总是返回第一个匹配项。然而,使用$'id',someContext将允许您获得第二、第三、第四。。具有完全相同id的元素。
var $detail = $("#detail");
init: function( selector, context ) {
    ...
    if ( typeof selector === "string" ) {
        ...
        // This gets ignored because we passed a context
        // document.getElementById() isn't called directly
        if ( match && (match[1] || !context) ) {
            ...
            } else {
                elem = document.getElementById( match[2] );
                ...
            }
        ...
        // Either this gets executed if a jQuery wrapped context was passed
        } else if ( !context || context.jquery ) {
            return (context || rootjQuery).find( selector );
        }
        // Or this gets executed, if a simple selector was passed as context
        } else {
            return jQuery( context ).find( selector );
        }
    ...
}