jQuery 是否对“选择器”进行任何类型的缓存?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/291841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does jQuery do any kind of caching of "selectors"?
提问by Allain Lalonde
For example, will the first piece of code perform a full search twice, or is it smart enough to cache results if no DOM changes have occurred?
例如,第一段代码是否会执行两次完整搜索,或者如果没有发生 DOM 更改,它是否足够智能以缓存结果?
if ($("#navbar .heading").text() > "") {
$("#navbar .heading").hide();
}
and
和
var $heading = $("#navbar .heading");
if ($heading.text() > "") {
$heading.hide();
}
If the selector is more complex I can imagine it's a non-trivial hit.
如果选择器更复杂,我可以想象这是一个不平凡的成功。
采纳答案by Neil C. Obremski
jQuery doesn't, but there's the possibility of assigning to variables within your expression and then use re-using those in subsequent expressions. So, cache-ifying your example ...
jQuery 没有,但有可能在表达式中分配变量,然后在后续表达式中重新使用这些变量。所以,缓存你的例子......
if ((cached = $("#navbar .heading")).text() > "") {
cached.hide();
}
Downside is it makes the code a bit fuglier and difficult to grok.
缺点是它使代码有点模糊且难以理解。
回答by gnarf
Always cache your selections!
始终缓存您的选择!
It is wasteful to constantly call $( selector )
over and over again with the same selector.
$( selector )
用同一个选择器不断地反复调用是很浪费的。
Or almost always... You should generally keep a cached copy of the jQuery object in a local variable, unless you expect it to have changed or you only need it once.
或者几乎总是...您通常应该在本地变量中保留 jQuery 对象的缓存副本,除非您希望它已更改或您只需要它一次。
var element = $("#someid");
element.click( function() {
// no need to re-select #someid since we cached it
element.hide();
});
回答by JoeBloggs
It's not so much a matter of 'does it?', but 'can it?', and no, it can't - you may have added additional matching elements to the DOM since the query was last run. This would make the cached result stale, and jQuery would have no (sensible) way to tell other than running the query again.
与其说是“可以吗?”,不如说是“可以吗?”,不,不能 - 自上次运行查询以来,您可能已经向 DOM 添加了额外的匹配元素。这将使缓存的结果过时,并且 jQuery 除了再次运行查询之外没有(明智的)方法来判断。
For example:
例如:
$('#someid .someclass').show();
$('#someid').append('<div class="someclass">New!</div>');
$('#someid .someclass').hide();
In this example, the newly added element would not be hidden if there was any caching of the query - it would hide only the elements that were revealed earlier.
在此示例中,如果查询有任何缓存,则不会隐藏新添加的元素 - 它只会隐藏之前显示的元素。
回答by Aleksandr Makov
I just did a method for solving this problem:
我刚刚做了一个解决这个问题的方法:
var cache = {};
function $$(s)
{
if (cache.hasOwnProperty(s))
{
return $(cache[s]);
}
var e = $(s);
if(e.length > 0)
{
return $(cache[s] = e);
}
}
And it works like this:
它的工作原理是这样的:
$$('div').each(function(){ ... });
The results are accurate as far as i can tell, basing on this simple check:
据我所知,结果是准确的,基于这个简单的检查:
console.log($$('#forms .col.r')[0] === $('#forms .col.r')[0]);
NB, it WILL break your MooTools implementation or any other library that uses $$
notation.
注意,它会破坏您的 MooTools 实现或任何其他使用$$
符号的库。
回答by Peter Boughton
I don't think it does (although I don't feel like reading through three and a half thousand lines of JavaScript at the moment to find out for sure).
我不认为它有(虽然我现在不想通读三千五万行 JavaScript 来确定)。
However, what you're doing does not need multiple selectors - this should work:
但是,您所做的不需要多个选择器 - 这应该有效:
$("#navbar .heading:not(:empty)").hide();
回答by Sefi Grossman
Similar to your $$ approach, I created a function (of the same name) that uses a memorization pattern to keep global cleaner and also accounts for a second context parameter... like $$(".class", "#context"). This is needed if you use the chained function find() that happens after $$ is returned; thus it will not be cached alone unless you cache the context object first. I also added boolean parameter to the end (2nd or 3rd parameter depending on if you use context) to force it to go back to the DOM.
与您的 $$ 方法类似,我创建了一个函数(同名),该函数使用记忆模式来保持全局清洁并考虑第二个上下文参数......例如 $$(".class", "#context" )。如果您使用在 $$ 返回后发生的链式函数 find() ,则需要这样做;因此,除非您先缓存上下文对象,否则它不会单独缓存。我还在末尾添加了布尔参数(第二个或第三个参数,具体取决于您是否使用上下文)以强制它返回到 DOM。
Code:
代码:
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];
}
Usage:
用法:
<div class="test">a</div>
<div id="container">
<div class="test">b</div>
</div>?
<script>
$$(".test").append("1"); //default behavior
$$(".test", "#container").append("2"); //contextual
$$(".test", "#container").append("3"); //uses cache
$$(".test", "#container", true).append("4"); //forces back to the dome
?
</script>
回答by Owen
i don't believe jquery does any caching of selectors, instead relying on xpath/javascript underneath to handle that. that being said, there are a number of optimizations you can utilize in your selectors. here are a few articles that cover some basics:
我不相信 jquery 会缓存任何选择器,而是依靠下面的 xpath/javascript 来处理它。话虽如此,您可以在选择器中使用许多优化。以下是一些涵盖一些基础知识的文章:
回答by Joschi
This $$() works fine - should return a valid jQuery Object in any case an never undefined.
这个 $$() 工作正常 - 在任何情况下都应该返回一个有效的 jQuery 对象,永远不会未定义。
Be careful with it! It should/cannot with selectors that dynamically may change, eg. by appending nodes matching the selector or using pseudoclasses.
小心点!它应该/不能使用动态可能改变的选择器,例如。通过附加与选择器匹配的节点或使用伪类。
function $$(selector) {
return cache.hasOwnProperty(selector)
? cache[selector]
: cache[selector] = $(selector);
};
And $$ could be any funciton name, of course.
当然,$$ 可以是任何函数名称。
回答by Anirban Deb
John Resig in his Jquery Internals talk at jQuery Camp 2008 does mention about some browsers supporting events which are fired when the DOM is modified. For such cases, the Selctor results could be cached.
John Resig 在 jQuery Camp 2008 的 Jquery Internals 演讲中确实提到了一些浏览器支持在修改 DOM 时触发的事件。对于这种情况,可以缓存选择器结果。
回答by justnorris
There is a nice plugin out there called jQachethat does exactly that. After installing the plugin, I usually do this:
有一个很好的插件叫做jQache就是这样做的。安装插件后,我通常这样做:
var $$ = $.q;
var $$ = $.q;
And then just
然后只是
$$("#navbar .heading").hide();
$$("#navbar .heading").hide();
The best part of all this is that you can also flush your cache when needed if you're doing dynamic stuff, for example:
最好的部分是,如果您正在执行动态操作,您还可以在需要时刷新缓存,例如:
$$("#navbar .heading", true).hide(); // flushes the cache and hides the new ( freshly found ) #navbar .heading
$$("#navbar .heading", true).hide(); // 刷新缓存并隐藏新的(新发现的)#navbar .heading
And
和
$$.clear(); // Clears the cache completely
$$.clear(); // 彻底清除缓存