2010-08-11 51 views
1

我想在浏览器中使用canvas元素创建基本频闪灯。我期待setInterval继续调用changeBG函数来改变为随机背景颜色。这个函数可以独立工作,但不能在setInterval调用时使用。我试图在firebug中拉起这个页面,它告诉我颜色是未定义的。这是有问题的代码。setInterval和未定义参数的问题

<html> 
<head> 
    <title>Strobe!</title> 
    <link rel="stylesheet" type="text/css" href="reset.css" /> 
    <script type="text/javascript"> 
     function changeBG(colors,ctx,canvas) {     
      ctx.fillStyle = colors[Math.floor(Math.random()*colors.length)] 
      ctx.fillRect(0,0,canvas.width,canvas.height) 
     } 

     function eventLoop() { 
      var colors = ['#000000','#ff0000','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff'] 
      var canvas = document.getElementById('mainCanvas') 
      var ctx = canvas.getContext('2d') 
      canvas.width = window.innerWidth 
      canvas.height = window.innerHeight 
      //changeBG(colors,ctx,canvas) 
      setInterval("changeBG(colors,ctx,canvas)", 1000);    
     } 
    </script> 
</head> 
<body onload="eventLoop()"> 
    <canvas id="mainCanvas" width="800" height="600"> 
    </canvas> 
</body> 

我是新来的JavaScript,因此任何见解什么那么将高度赞赏。

回答

6

你的代码会工作。因为它在一个字符串中,所以它不能在你试图使用的变量上创建一个闭包。

试试这个:

setInterval(function() { 
    changeBG(colors,ctx,canvas); 
}, 1000)​;​ 

使用这种方法,你传递一个匿名函数给setInterval。它将在每个间隔内调用一次该函数,在本例中为1000毫秒。

该函数可以使用颜色,ctx和canvas变量,因为它们存在于函数声明的范围中。这将创建一个闭包,以便这些变量在我们反复调用时仍然存在(就我们的匿名函数而言)。

现在,您可能只需使用此代码即可。为了进一步理解,我建议研究匿名函数和闭包。

+1

只是为了OP的完整性:如果您将'colors','ctx'和'canvas'变量声明为全局变量,而不使用'var',则代码有效。为什么?因为变数现在是全球性的。每当有人这样做时,上帝会杀死一只小猫(几乎)。 – Chubas 2010-08-11 21:29:58

+1

非常感谢。我曾经与死猫一起试过这个版本,但我的良知无法接受。 – 2010-08-11 21:52:10

+1

@Chubas:正确。我会提到的,但忘了! – EndangeredMassa 2010-08-11 22:32:26

-1

试试这个 修订 setInterval(function(){changeBG(colors,ctx,canvas)}, 1000);

+0

+1对我来说很不错 – 2010-08-11 21:11:46

+1

我不认为你需要在这个例子中的匿名函数声明的参数。这将阻止使用现有变量,因为该函数将期望它们作为输入并将它们视为未定义(如果未提供)。 – 2010-08-11 21:26:48

+0

是的,我们不需要重新声明它... – shox 2010-08-11 22:18:42

0

您可以直接传递一个函数,而不是字符串来评估,如

setInterval(function(){changeBG(colors,ctx,canvas)}, 1000); 

好运挑起癫痫的人

0

问题的根源当间隔代码执行时,变量作用域,颜色和其他变量不在作用域中。

试试这个:如果你不是传递字符串给setInterval

<html> 
<head> 
<title>Strobe!</title> 
<link rel="stylesheet" type="text/css" href="reset.css" /> 
<script type="text/javascript">   
    function eventLoop() { 
     var colors = ['#000000','#ff0000','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff'] 
     var canvas = document.getElementById('mainCanvas') 
     var ctx = canvas.getContext('2d') 
     canvas.width = window.innerWidth 
     canvas.height = window.innerHeight    
     setInterval(function() {     
      ctx.fillStyle = colors[Math.floor(Math.random()*colors.length)] 
      ctx.fillRect(0,0,canvas.width,canvas.height) 
     }, 1000);    
    }  
</script> 
</head> 
<body onload="eventLoop()"> 
    <canvas id="mainCanvas" width="800" height="600"> 
    </canvas> 
</body>