jquery dom操作性能

背景

在代码review的时候,遇到了个问题,请大神指导下
个人代码中有多处dom操作。
类似:
获取模块:$("#all")
多次获取a:$("#a")
多次获取b:$("#b")

老大给出两个建议:

  • 多次使用的dom,保存
    var aObj = $("#a");

  • 对于a,b,c都在all中操作。要首先保存all,减少全局检索
    var viewObj = $("#all");
    var aObj = $("#a",viewObj)

问题来了

两个建议理论上都木有问题,但是,第二种实现方式

var aObj = $("#a",viewObj)

这个会在viewObj 内部检索吗?jquery 有相关资料吗?

阅读 4.4k
6 个回答

$() 这个方法完全体是这样的:

jQuery([selector,[context]])

第二个参数可选, 它是selector的查找范围, 如果未指定, 可以理解为查找范围就是document

下面两个会查找到同样的dom集合:

$('.parent .child')
$('.child','.parent')

这两个参数都可以接受字符串,dom元素,jquery对象作为参数。
相关资料可以直接看jqueryAPI,核心方法第一个就是。

jQuery( selector [, context ] ) 用法的官方的说明:

Selector Context
By default, selectors perform their searches within the DOM starting at the document root. However, an alternate context can be given for the search by using the optional second parameter to the $() function. For example, to do a search within an event handler, the search can be restricted like so:

$( "div.foo" ).click(function() {
 $( "span", this ).addClass( "bar" );
});

When the search for the span selector is restricted to the context of this, only spans >within the clicked element will get the additional class.
Internally, selector context is implemented with the .find() method, so $( "span", this ) is equivalent to $( this ).find( "span" ).

意思是会在指定的Context,也就是指定的DOM元素内查找;jquery内部使用find方法来实现

先说 结论 如果是仅仅是id选择器, 也就是楼主问的

var aObj = $("#a")
var aObj = $("#a",viewObj)

第一种效率高,因为第一种直接 document.getElementById
https://github.com/jquery/jquery/blob/master/src/core/init.js#L77

第二种 走的是jQuery.find jQuery.find = Sizzle ,
https://github.com/jquery/jquery/blob/master/src/core/init.js#L90
https://github.com/jquery/jquery/blob/master/src/core/init.js#L95
https://github.com/jquery/jquery/blob/5943f1d7ffef41cc1a99bffe189f6d111fbccfd0/src/selector-sizzle.js#L6

jQuery源码
https://github.com/jquery/jquery/blob/master/src/core/init.js#L16

// Shortcut simple #id case for speed
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/
rquickExpr.exec('#a') // ["#a", undefined, "a"]
rquickExpr.exec('.a') // null
rquickExpr.exec('#a .a') // null
rquickExpr.exec('<div id="a"></div>') // ["<div id="a"></div>", "<div id="a"></div>", undefined]

rquickExpr macth 单一id选择器,或者html tag

Sizzle
https://github.com/jquery/jquery/blob/5943f1d7ffef41cc1a99bffe189f6d111fbccfd0/external/sizzle/dist/sizzle.js#L132

// Easily-parseable/retrievable ID or TAG or CLASS selectors
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
rquickExpr.exec('#a') // ["#a", "a", undefined, undefined]
rquickExpr.exec('.a') // null
rquickExpr.exec('#a .a') // null
rquickExpr.exec('<div id="a"></div>') // null
var $aaa = $('#aaa');

var $bbb = $aaa.find('.bbb');    // 多次使用
$aaa.find('.ccc');                // 一次使用

因为$()是个方法,是方法就会有执行时间

每次$()起来保存给变量使用

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题