如何优化这个jquery循环的执行时间
How can I optimize execution time of this jquery loop?
我有一个循环,它通过类为"GridCell"的表cel中的所有div。在某些情况下,当调整网格或列的大小时,需要发生这种情况。
我扩展了行和列的数量,以查看更多的时间差,现在循环大约是750毫秒。
但我不明白的是,"只是循环的一部分"要快得多。请参见以下三个循环。第一个是缓慢的。只做第一个循环的一部分的第二个和第三个循环真的很快。
//Around 750 ms
$('table.Grid tbody td.GridCell > div').each(function() {
var width = $(this).parent().width();
$(this).css('width', width - 3);
});
//Around 60 ms
$('table.Grid tbody td.GridCell > div').each(function() {
var width = $(this).parent().width();
});
//Around 15 ms
$('table.Grid tbody td.GridCell > div').each(function() {
$(this).css('width', 100);
});
所以一条线只有60或15毫秒,但两者加起来是750毫秒。这有什么不同?
p.s.我执行循环的顺序并不重要。第一个循环总是比其他循环慢得多,也是在最后执行该循环时。
// collect the widths from the first row only
var widths = $('table.Grid tbody tr:first-child td.GridCell').map(function(idx) {
return $(this).width() - 3;
// or use:
// return this.clientWidth - 3;
// if you're not targeting IE <= 7
});
// apply the widths to each div
$('table.Grid tbody td.GridCell > div').each(function(idx) {
this.style.width = widths[idx % widths.length] + 'px';
});
在第一个循环中,计算一个计算的宽度,然后将其应用于每次迭代的另一个元素。在第二个循环中,您所要做的就是计算宽度,并将其分配给一个变量。在第三个循环中,您只是简单地应用静态内联样式。
我想说的是,最后两个循环加起来并不等于第一个循环的功能,所以第一个循环比其他两个循环的加起来慢也就不足为奇了。
你应该试试这样的东西:
var $divs = $('table.Grid tbody td.GridCell > div'),
m = [];
// case 1
$divs.each(function() {
var width = $(this).parent().width();
$(this).css('width', width - 3);
});
// case 2
$divs.each(function() {
m.push( $(this).parent().width() );
}).each(function(i) {
$(this).css('width', m[i] - 3);
});
我在这里做了一个简单的性能测试:http://jsperf.com/tablewidth而且差别似乎很小。
var $rows = $('table.Grid tbody').children('tr');
// we only need the widths from the first row
var widths = $rows.first().children('td').map(function() {
return $(this).width() - 3;
}).get();
// process each row individually
$rows.each(function() {
$('td.gridCell > div', this).css('width', function(i) {
return widths[i];
});
});
假设父宽度的计算不是动态的(子宽度的大小不会影响父宽度),并且宽度是恒定的(big if’s)。
var width = $(this).parent().width();
$('table.Grid tbody td.GridCell > div').each(function() {
$(this).css('width', width - 3);
});
在您的第一个示例中
$('table.Grid tbody td.GridCell > div').each(function() {
var width = $(this).parent().width();
$(this).css('width', width - 3);
});
您正在对$(this)
进行两次评估。试着写
$('table.Grid tbody td.GridCell > div').each(function() {
var $this = $(this);
var width = $this.parent().width();
$this.css('width', width - 3);
});
或者
each()
方法传递的当前元素
$('table.Grid tbody td.GridCell > div').each(function(i, el) {
var $this = $(el);
var width = $this.parent().width();
$this.css('width', width - 3);
});
我很难说出确切的细节,但我理解这个问题:
var width = $(this).parent().width();
-你调用这个,浏览器会强制你获得所选元素的真实尺寸。$(this).css('width', 100);
-这会导致浏览器回流文档。所以您运行此行,浏览器必须重新计算页面的一部分。
为什么第一个循环的工作速度比其他两个循环慢?我认为,当你只做var width = $(this).parent().width();
时,它可以计算一次所有宽度,并从缓存中给出它们。现在,当您只执行这一行时,$(this).css('width', 100);
浏览器可以等待,直到脚本执行完毕。并一次重新绘制所有更新元素。但当您执行第一个循环时,您会强制浏览器计算宽度,而不是更新某些元素。维度缓存已损坏。现在您再次想要获得宽度,浏览器必须重新绘制页面。因此,每个循环都会重新绘制一页,与其他两个循环相反,而它只能这样做一次。
这不一定是JS问题 忘记循环,您根本不需要使用JS/jQuery来实现所需的功能。
要使.GridCell
的子div占用所有可用宽度减去3px,可以使用以下CSS规则:
.GridCell>div {
width:auto; /*take up all available width (for block elements)*/
margin:0 1.5px; /*add a 1.5px buffer on both sides of the div*/
}
如果你真的很喜欢,不在乎浏览器兼容性矩阵有点差,你可以依赖CSS3 calc()
:
.GridCell>div {
width:calc(100% - 3px); /*look up vendor-specific prefixes of the property
if you want for this to work on more browsers*/
margin: 0 auto; /*now that the width is calculated correctly above,
center the div. Or don't!*/
}
Et voila
好吧,这里有另一个选择:
$('table.Grid tbody td.GridCell > div').css('width', function() {
return $(this.parentNode).width() - 3;
});
如果你使用怎么办
$('table.Grid tbody td.GridCell > div').each(function(i,domEle) {
$(domEle).css('width', $(domEle).parent().width() - 3);
});
并尝试在jQuery 中使用优化选择器
- jQuery:循环一个具有不同超时值的循环
- jQuery循环在特定位置暂停
- 循环中的jQuery循环
- 使用val()在jquery循环中设置html字符串的val
- $.每个jquery循环打印一个“;未定义的“;对于getJSON请求后的每个元素,网格数据都会完美地打印出来
- jQuery循环寻呼机附加较小的图像大小
- 如何优化这个jquery循环的执行时间
- Jquery循环停止按钮
- 如何使用jQuery循环变量名
- Jquery循环洗涤器插件:添加到图像的链接
- 遍历 jQuery:循环遍历子项
- Javascript / JQuery循环访问已发布的ajax数据字符串以为其分配新值
- Jquery 循环一次或在数据数组中显示一次数据
- Jquery 循环与名称 increament.
- jQuery 循环 JSON 结果,对象作为值
- 正在尝试将jquery鼠标滚轮插件插入到jquery循环2中
- jQuery循环遍历每个li并检查一个类
- 使用jQuery循环遍历颜色数组
- 使用jquery循环表行并通过类名访问数据
- 对未知数量的元素执行Jquery循环