我正在尝试学习一些优化我的jQuery代码...
有没有办法改进下面的代码,以便变量$ selected在函数之外声明,但仍然可以访问,这样每次都不会遍历DOM?
或者这段代码是否尽可能优化?
或者......我想我可能误解了jquery DOM遍历的发生方式和时间。
$('#full-width-layout_c1_col-1-1_1').on(
'mouseenter mouseleave click',
'a.project_open, a.song_open',
function(e) {
var $selected = $(this).closest('tr').find('div');
if (e.type == 'mouseenter') {
$selected.addClass("hovered");
}
else if (e.type == 'mouseleave'){
$selected.removeClass("hovered");
}
else if (e.type == 'click'){
$selected.addClass('opened');
}
}
);
答案 0 :(得分:2)
您可以使用某种缓存 - 单击某个元素时,将$selected
作为数据存储到元素中,以便从元素中提取$selected
的任何时间,而不是通过执行DOM遍历:
var $selected = $(this).data("closestdiv");
if(!$selected) { // first time
$selected = $(this).closest('tr').find('div');
$(this).data("closestdiv", $selected);
}
答案 1 :(得分:2)
如果在DOM元素中存储任意数据时需要最后一点性能,请不要使用jQuery.data()
。这会表现得更好:
var $selected = this.closestdiv;
if(!$selected) { // first time
$selected = $(this).closest('tr').find('div');
this.closestdiv = $selected;
}
通过这个简单的基准http://jsperf.com/jquerydata/4,您可以看到将数据直接存储在DOM上的速度有多快,而不是使用jQuery.data()
。在我的机器上使用 jQuery.data()
比直接存储数据慢97%。同样,公平的警告 - jQuery.data()
有一定的开销,因为它试图对事物保持聪明并防止潜在的内存泄漏。
答案 2 :(得分:0)
由于您选择了ID,并且我认为您只有一个具有此ID的元素,因此您可以在事件处理程序之外使用它:
var $selected = $('#full-width-layout_c1_col-1-1_1').closest('tr').find('div');
这也假设不会进行任何可能改变上述语句返回的DOM操作。
编辑:没关系。我误读了。遗憾。答案 3 :(得分:0)
没有看到您的HTML很难确定,但我怀疑您无法查找要修改的DIV,因为对于每个点击的锚点它都不同。既然如此,您每次都需要遍历点击/悬停元素中的DOM。
答案 4 :(得分:0)
这不是答案,但几乎没有机会减少代码:
$('#full-width-layout_c1_col-1-1_1').on(
'mouseenter mouseleave click',
'a.project_open, a.song_open',
function(e) {
var $selected = $(this).closest('tr').find('div');
if (e.type === 'click'){
$selected.addClass('opened');
} else {
$selected.toggleClass('hovered');
}
);
答案 5 :(得分:0)
您可以使用闭包:
(function () {//scoping function
var $selected = $(this).closest('tr').find('div');
$('#full-width-layout_c1_col-1-1_1').on(
'mouseenter mouseleave click',
'a.project_open, a.song_open',
function(e) {
if (e.type == 'mouseenter') {
$selected.addClass("hovered");
}
else if (e.type == 'mouseleave'){
$selected.removeClass("hovered");
}
else if (e.type == 'click'){
$selected.addClass('opened');
}
}
);
}()); //end scoping function
这将使div的搜索只发生一次。