有很多问题要求缓存jQuery对象,但我找不到一个询问jQuery对象可以和应该缓存的位置。我有一个网页,其中包含一个包含一系列功能的JavaScript文件,如下所示。
$(document).ready(function () {
// do some setup
});
/* function queries the DOM with the same selector multiple times without caching */
function myFunctionOne() {
$('#name_input').css("border","1px solid #ccc");
$('#name_input').val(someValue);
}
/* function uses cached object from a single query */
function myFunctionTwo() {
var nameInput = $('#name_input')
nameInput.css("border","1px solid #ccc");
nameInput.val(someValue);
// do some other stuff with cached selector
}
在myFunctionOne
我低效地查询DOM两次,而在myFunctionTwo
我查询DOM一次,将结果缓存在局部变量中,然后使用该变量。我理解myFunctionTwo
中的方法更有效但我不确定我应该在哪里实际缓存这些对象。在那一刻我在方法级别缓存对象,但我想知道我是否可以实际缓存它在更高级别,然后在多个函数中使用它。这样我只会查询一次DOM,然后在该文件的所有函数中重用结果。我建议的一个例子如下所示。
$(document).ready(function () {
// do some setup
var nameInput = $('#name_input')
});
/* function uses cached query result from .ready function above */
function myFunctionOne() {
nameInput .css("border","1px solid #ccc");
nameInput .val(someValue);
}
/* function uses cached query result from .ready function above */
function myFunctionTwo() {
nameInput.val(someValue);
// do some other stuff with cached selector
}
这种方法是否合理或有更好的方法吗?也许使用.ready函数是一个不好的地方进行这种设置,因为它会减慢页面加载?是否有另一种方法可以在对象级别缓存jQuery对象,还是只应在函数级别缓存它们?
答案 0 :(得分:8)
一如既往地在这些问题中,不要过早优化。在这种情况下,它意味着在您发现性能问题之前不要使用任何缓存。如果您的目标客户使用的是低规格的计算机或移动设备,这意味着您需要自己在低规格硬件上进行测试,以便识别出这些问题。我强烈建议您在尝试通过添加缓存来提高速度之前先明确一下。
还有一些要点:
getElementById
,因此不需要缓存。.ready
很好。它在加载DOM后运行,是完成设置任务的正确位置。答案 1 :(得分:1)
一种方法可能是将选择器存储在$.cache
:
$(function(){
var $nameInput = $('#name_input');
$('body').data({ nameInput: $nameInput });
});
然后使用以下方式访问它:
function myFunctionOne() {
var $nameInput = $('body').data('nameInput');
}
答案 2 :(得分:-1)
这段代码会很好地混淆。您可以在_initControls中添加任意数量的控件,并在以后的整个脚本块中使用它们。如果您希望它对所有脚本块都是全局的,那么将_initControls函数移出jQuery onreadystate函数。
$(function () {
"use strict";
var _controls = {},
_init = function () {
_initControls();
_updateData("Hello");
},
_initControls = function () {
_controls.nameInput = $("#name_input");
},
_updateData = function (value) {
var nameInput = _controls.nameInput;
nameInput.css("border", "1px solid #ccc");
nameInput.val(value);
};
_init();
});