我有这个简单的jQuery调用来突出显示一堆元素(几千个):
jQuery(elem).addClass('highlighted');
浏览器的作用是快速添加类,但不重新绘制元素。有没有办法在我添加类时立即呈现每个“突出显示”元素。现在,用户看到了一个口吃,直到我添加类的循环结束。
更多代码:
var elem = findNext(); // walks the dom and finds next search match. ~10ms each call
while(elem){
highlight(elem);
elem = findNext();
}
function highlight(elem){
jQuery(elem).addClass('highlight');
...
}
答案 0 :(得分:3)
这是因为只要JavaScript函数正在运行,就不会呈现DOM更改。用户界面代码是单线程的,浏览器在执行时会锁定。通常这不是问题,因为JS非常快并且函数运行时间不长。但如果他们这样做,你就会看到缓慢的行为。
您的功能需要在其工作中停止,以使浏览器有机会再次响应。您可以使用setTimeout()
并记住上次停止的位置来解决此问题。
这应该会给你一个想法:
// prepares a closure function to handle affected elements in chunks of n
function updatePartial(elems, chunksize) {
var current = 0;
return function() {
// changes n elements in a loop
for (var i=0; i<chunksize; i++) {
jQuery(elems[current+i]).addClass('highlighted');
}
current += chunksize;
// calls itself again after a short break
if (current < elems.length) setTimeout(arguments.callee, 10);
}
}
// aquire and execute the closure function
updatePartial(jQuery("selector").get(), 100)();
(经http://jsfiddle.net/fPdAg/测试)
闭包是一种避免在其他实现中需要的全局变量的优雅方法。
编辑:以上的通用版本是:
// prepares a closure function to handle affected elements in chunks of n
function updatePartial(elems, chunksize, payload) {
var current = 0;
return function() {
// changes n elements in a loop
for (var i=0; i<chunksize; i++) {
// apply the payload function to current element
payload.apply(elems[current+i]);
}
current += chunksize;
// calls itself again after a short break
if (current < elems.length) setTimeout(arguments.callee, 10);
}
}
// aquire and execute the closure function, supply custom payload function
updatePartial(jQuery("selector").get(), 100, function() {
jQuery(this).addClass('highlighted');
})();
答案 1 :(得分:1)
jQuery(elem).addClass('highlighted');
当 Javascript runnig时,浏览器会停止工作,直到JS完成执行。所以浏览器不会重新发布任何东西,直到JQuery addClass到每个元素 试试这个技巧
<script>
x = jQuery(elem).size();
y = number_item_each_time;
z = time_by_micro;
start = 0;
t = setInterval(function(){
$(elem).slice(start, start + y).addClass('highlighted');
start = start + y;
if(start > x)
clearInterval(t);
}, z);
</script>
答案 2 :(得分:0)
您确定浏览器正在快速添加课程吗?听起来这需要相当长的时间来完成操作,这正是我所期望的。
您可以尝试将addClass()调用批处理为一系列setTimeout回调(例如,每次执行100个元素的10个调用)以更快地显示结果。
<强>更新强>
我刚注意到你说“直到我添加课程的循环完成”。您是否只对addClass进行一次调用,或者为for循环中的每个元素单独调用它?
你绝对应该拨打一个电话jQuery('.all-your-elements').addClass('highlighted')
。它会更具可读性和更快。
答案 3 :(得分:0)
仅使用jQuery 1.4.2检查解决方案(不带setTimeout) 它使用$(document)上的队列来推迟函数执行 并按顺序执行它们。
$(function() {
$('.highlight').each(function() {
var e = $(this);
$(document).delay(1000).queue(function(next) {
e.addClass('a');
next();
});
});
});