【问题标题】:HTML5/Javascript timeout doesn't finish functionHTML5/Javascript 超时未完成功能
【发布时间】:2012-03-04 12:40:16
【问题描述】:

我做了一个循环函数来慢慢淡化图像。

var ctx; // this is the canvas already defined
function nextPic(i)
    {
        trans = 1; //resets transparent var to 1
        fadeloop('out'); //starts loop
        ctx.clearRect(0, 0, canvas.width, canvas.height); //clears canvas, this doesn't work
        alert("done"); //this doesn't work either

    }
    function fadeloop(f){ //loop that fades
        if(f == 'out'){ //make sure it wants to shade out
            setTimeout(function () { //timed delay for fading out
                fadeImgOut(); //calls function to fade out by .01
                if(trans>0.0){ //if faded out break out of loop
                    fadeloop('out'); //if not restart function
                }
            },10);
        }
    }
    function fadeImgOut(){ //function that fades out
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img,0,0);
        ctx.globalAlpha = trans;
        trans = trans - .01;
    }

一个按钮调用nextpic。它会慢慢透明图像,然后淡入另一个。现在它淡出图像直到 trans = .01。不会继续到警报(“完成”)或画布重置。任何想法,我一遍又一遍地查看,但不知道该怎么做。

【问题讨论】:

  • 您在网络检查器中遇到错误吗?如果警报(“完成”)没有触发,我猜脚本会因任何原因而崩溃。
  • canvas.width & canvas.height在哪里定义?
  • 另外,你现在在哪里声明 'trans'对于 ctx。
  • 没有var 关键字。因此,如果他没有在某个地方明确声明它,那么它就是一个全球性的——在这里不应该是个问题。我想知道的是,如果 OP 没有意识到他对fadeloop 的初始调用会立即返回,而不是由于setTimeout 而在所有递归结束时返回。
  • 我没有收到任何错误,也没有崩溃。它只是完全忽略它。画布在顶部附近定义。忘记包含该变量,但它可以工作。声明了一些变量,但未在此处声明,因为我不知道将其粘贴在示例代码中的哪个位置。 Canvas、ctx、trans 都被声明了。

标签: javascript html function loops timeout


【解决方案1】:

我用类似的功能进行了测试。代码是:



    var j = 100;
    (function(){
        a();  // step 1;
        alert("hello world!"); // step 3; Fired without almost no time delay.
    })()

    function a(){
        setTimeout(function(){
           b();
           if(j>1){
              a();
           }
        }, 10); // step 2;  push the callback into a queue, and a() ends. 
    }

    function b(){
        if(j > 1){
            j--;
        }
    }

结果是:立即触发警报,没有任何延迟。结果是对的。

因为 setTimeout 是异步函数。这意味着当 a() 第一次执行时, setTimeout 中的回调函数将被推送到等待触发的队列中。然后expression function 中的 alert() 被触发。

我不知道为什么您的警报没有被触发。可能发生了一些错误。

【讨论】:

    【解决方案2】:

    这可能无法解决您的问题,但可能会简化一点。

    您正在递归地使用fadeloop,但您可以通过while 循环简单地完成此操作,这样更容易跟踪/调试。并且不必弄清楚您在递归中的深度。

    我能想到的唯一问题是 setTimeout 是否有 setTimeout(function, time) 的方法签名?其他一切看起来都正确。

    【讨论】:

    • while 循环不起作用。它出现故障,指南告诉我这样写。是的,setTimeout 确实如此。
    【解决方案3】:

    trinity 的答案是正确的,尽管警报未触发确实听起来像是您有其他错误干扰了发布的代码。 FWIW,这是一个包含您的代码的最小页面,表明它按描述工作:

    <!doctype html>
    <canvas id="canvas"></canvas>
    <script>
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var img = new Image();
    img.onload = nextPic;
    img.src = 'http://cdn.sstatic.net/careers/ads/img/careers2-ad-header-so-crop.png';
    
    function nextPic(i) {
      trans = 1; //resets transparent var to 1
      fadeloop('out'); //starts loop
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      alert("done");
    }
    function fadeloop(f){ //loop that fades
      if(f == 'out'){ //make sure it wants to shade out
        setTimeout(function () { //timed delay for fading out
          fadeImgOut(); //calls function to fade out by .01
          if(trans>0.0){ //if faded out break out of loop
            fadeloop('out'); //if not restart function
          }
        },10);
      }
    }
    function fadeImgOut(){ //function that fades out
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img,0,0);
      ctx.globalAlpha = trans;
      trans = trans - .01;
    }
    </script>
    

    请注意,您订购事物的方式(绘制后从 trans 中减去,然后 检查是否应该重复循环),您将在 0.01 附近结束是正确的。您需要重新排序以确保达到 0。

    还要小心重复的浮点减法:你没有达到你认为的值(并且你永远不会通过这个循环达到精确的 0)。一个很小的改变就可以让你开始正确(这假设你的图像已经绘制了一次,所以可以在调用fadeImgOut之前从trans中减去):

    function fadeloop(f){ //loop that fades
      if(f == 'out'){ //make sure it wants to shade out
        setTimeout(function () { //timed delay for fading out
          trans = Math.max(0, trans - .01);
          fadeImgOut(); //calls function to fade out by .01
          if(trans>0.0){ //if faded out break out of loop
            fadeloop('out'); //if not restart function
          }
        },10);
      }
    }
    function fadeImgOut(){ //function that fades out
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.globalAlpha = trans;
      ctx.drawImage(img,0,0);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-04
      • 1970-01-01
      • 2013-10-11
      • 2012-01-09
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多