1

我有一个包含 10,000 多个元素的 html ul 列表,并且想要添加自定义悬停工具提示事件并对每个元素进行一些其他处理。在 document.ready 上执行此操作需要 2-3 秒并冻结浏览器。如何异步执行此操作以使浏览器不会冻结?

我一直在阅读有关 setTimeout、jQuery 队列和延迟的内容,但也许我太密集了,无法理解这一切。这家伙有有趣的东西http://erickrdch.com/2012/05/asynchronous-loop-with-jquery-deferred.html

这是我的 each() 循环,它添加了悬停。

$('#biglist li').each(function(index) {
    $(this).hover(function(e){
        ...do stuff...
    });
});

谢谢你的帮助。

4

3 回答 3

4

为什么你把它包裹在一个循环中?尝试使用.on()将悬停应用到#biglist ,然后委托给每个 li:

$('#biglist').on('hover','li', function(){
    // do crap
});

.each() 循环可能会通过对每个项目进行处理而造成严重破坏。附带说明一下,如果您需要为 mouseenter 和 mouseleave 执行不同的功能,您需要使用 XML 格式(使用 .on() 方法与传统的 .hover() 方法略有不同):

$('#biglist').on({
    mouseenter: function(){
        // do mouseenter crap
    },
    mouseleave: function(){
        // do mouseleave crap
    }
},'li');

无论哪种方式,这都应该大大减少处理过程中的 CPU 消耗。

于 2013-02-14T23:25:44.697 回答
3

您应该将其绑定到#bigListusing .on(),而不是 10,000 多个元素:

$('#bigList').on('hover', 'li', function(e) {
  // ...
});
于 2013-02-14T23:26:04.270 回答
1

浏览器 JavaScript 不支持真正的并发(即除了尖端的 HTML5 功能),因此您不能在页面继续正常工作的同时在后台运行一个进程。

您可以做的最好的 AFAIK 是将您的处理代码切成尽可能小的块,然后使用setTimeoutor执行它们setInterval,使用较低的延迟值(但最好是非零,因此页面的其余部分不会冻结)。

撇开您不需要hover为每个元素使用不同的处理程序这一事实不谈,正如其他人指出的那样,如果您需要对接收到的数据进行大量处理(并且这种处理不能由服务器完成),一种方法是使用队列:

var queue = [];
setInterval(function() {
    var next = queue.shift();
    if ( next ) next();
},50);

...

$.each(lotsOfData, function(index, value) {
    queue.push(function() {
        // Code for processing the value
    });
});
于 2013-02-14T23:25:46.483 回答