例如,第一段代码是否会执行两次完整搜索,或者如果没有发生DOM更改,它是否足够智能以缓存结果?
if ($("#navbar .heading").text() > "") { $("#navbar .heading").hide(); }
和
var $heading = $("#navbar .heading"); if ($heading.text() > "") { $heading.hide(); }
如果选择器更复杂,我可以想象它是一个非平凡的命中.
$( selector )
使用相同的选择器不断地一遍又一遍地调用是浪费的.
或者几乎总是......你通常应该在局部变量中保存jQuery对象的缓存副本,除非你期望它已经改变或者你只需要它一次.
var element = $("#someid"); element.click( function() { // no need to re-select #someid since we cached it element.hide(); });
jQuery没有,但是有可能在表达式中分配变量,然后在后续表达式中重用它们.所以,缓存 - 如果你的例子......
if ((cached = $("#navbar .heading")).text() > "") { cached.hide(); }
缺点是它使代码有点琐碎,难以理解.
这不是"它是什么?"的问题,而是"可以吗?",不,它不能 - 自上次运行查询以来,您可能已经向DOM添加了其他匹配元素.这会使缓存的结果失效,并且除了再次运行查询之外,jQuery没有(合理的)方式来告诉其他人.
例如:
$('#someid .someclass').show(); $('#someid').append('New!'); $('#someid .someclass').hide();
在此示例中,如果查询有任何缓存,则不会隐藏新添加的元素 - 它将仅隐藏先前显示的元素.
我刚刚做了一个解决这个问题的方法:
var cache = {}; function $$(s) { if (cache.hasOwnProperty(s)) { return $(cache[s]); } var e = $(s); if(e.length > 0) { return $(cache[s] = e); } }
它的工作原理如下:
$$('div').each(function(){ ... });
基于这个简单的检查,结果是准确的,据我所知:
console.log($$('#forms .col.r')[0] === $('#forms .col.r')[0]);
注意,它会破坏您的MooTools实现或使用$$
符号的任何其他库.
我不认为它(虽然我现在不想通过阅读三千五百行的JavaScript来确定).
但是,你正在做的不需要多个选择器 - 这应该工作:
$("#navbar .heading:not(:empty)").hide();
与你的$$方法类似,我创建了一个函数(同名),它使用记忆模式来保持全局清洁,并且还考虑了第二个上下文参数......比如$$(".class","#content" ).如果你使用返回$$后发生的链式函数find(),则需要这样做; 因此,除非先缓存上下文对象,否则不会单独缓存它.我还在末尾添加了布尔参数(第二个或第三个参数,具体取决于你是否使用了上下文)来强制它返回到DOM.
码:
function $$(a, b, c){ var key; if(c){ key = a + "," + b; if(!this.hasOwnProperty(key) || c){ this[key] = $(a, b); } } else if(b){ if(typeof b == "boolean"){ key = a; if(!this.hasOwnProperty(key) || b){ this[key] = $(a); } } else{ key = a + "," + b; this[key] = $(a, b); } } else{ key = a; if(!this.hasOwnProperty(key)){ this[key] = $(a); } } return this[key]; }
用法:
a?b