2010-06-08 44 views
12

我有一些JavaScript函数需要大约1到3秒。 (一些循环或mooML模板代码)。显示javascript执行进度

在此期间,浏览器刚被冻结。我试图在开始操作之前显示一个“加载”动画(gif图像)并将其隐藏起来。但它不起作用。浏览器在渲染图像之前冻结,并在函数结束时立即隐藏。

有什么我可以做,告诉浏览器之前进入JavaScript执行更新屏幕,喜欢的东西Application.DoEvents或后台工作线程。

因此,有关如何显示JavaScript执行进度的任何意见/建议。我的主要目标浏览器是IE6,但也应该对所有最新的浏览器

+0

你有没有尝试把JavaScript放入window.onload事件? – NibblyPig 2010-06-08 08:40:13

+0

@SLC它不属于那里 – Midhat 2010-06-08 08:58:41

回答

19

这是由于IE6中的所有内容都在相同的线程中执行 - 甚至是为gif制作动画。

确保在启动之前显示gif的唯一方法是通过分离执行。

function longRunningProcess(){ 
    .... 

    hideGif(); 
} 

displayGif(); 
window.setTimeout(longRunningProcess, 0); 

但是,当longRunningProcess执行时,这仍然会导致浏览器冻结。
为了让互动,你将不得不打破你的代码,以更小的片段,也许这样

var process = { 
    steps: [ 
     function(){ 
      // step 1 
      // display gif 
     }, 
     function(){ 
      // step 2 
     }, 
     function(){ 
      // step 3 
     }, 
     function(){ 
      // step 4 
      // hide gif 
     } 
    ], 
    index: 0, 
    nextStep: function(){ 
     this.steps[this.index++](); 
     if (this.index != this.steps.length) { 
      var me = this; 
      window.setTimeout(function(){ 
       me.nextStep(); 
      }, 0); 
     } 
    } 
}; 

process.nextStep(); 
+0

真棒...很酷的修复。谢谢 – Novice 2010-08-05 16:12:13

1

也许你可以把显示gif动画和运行重码之间的延迟工作。

显示GIF和呼叫:

window.setTimeout(myFunction, 100) 

做重的东西在 “myFunction的”。

0

尝试在运行该功能之前设置wait光标,然后再将其移除。在jQuery中,您可以这样做:

var body = $('body'); 
body.css("cursor", "wait"); 
lengthyProcess(); 
body.css("cursor", ""); 
+2

没有jQuery,它甚至是_shorter_! 'document.body.style.cursor = “等待”'。神奇! – Alsciende 2010-06-08 10:07:47

+0

@Alsciende,实际上,它更长。 'document.body.style.cursor =“等待”''对$(“身体”)。CSS(“光标”,“等待”)',但我认为,每个人都应该使用可用的最简单的方法。 – 2010-06-08 10:26:58

+5

事实上,jQuery的解决方案是非常70K长... – 2010-06-08 11:26:42

1

你必须使用一个小更先进的技术来显示长期运行的功能进展。

比方说,你有这样的功能,运行足够长的时间:

function longLoop() { 
    for (var i = 0; i < 100; i++) { 
     // Here the actual "long" code 
    } 
} 

为了保持界面的响应并显示进度(也避免了“脚本花费的时间太长......”在一些消息浏览器),您必须将执行分成几个部分。

function longLoop() { 
    // We get the loopStart variable from the _function_ instance. 
    // arguments.callee - a reference to function longLoop in this scope 
    var loopStart = arguments.callee.start || 0; 

    // Then we're not doing the whole loop, but only 10% of it 
    // note that we're not starting from 0, but from the point where we finished last 
    for (var i = loopStart; i < loopStart + 10; i++) { 
     // Here the actual "long" code 
    } 

    // Next time we'll start from the next index 
    var next = arguments.callee.start = loopStart + 10; 
    if (next < 100) { 

     updateProgress(next); // Draw progress bar, whatever. 
     setTimeout(arguments.callee, 10); 
    } 
} 

我还没有测试过这个实际的代码,但我之前使用过这种技术。

+0

我喜欢这个解决方案,谢谢! – 2013-05-31 22:20:42