Проблема с setInterval и неопределенными аргументами - PullRequest
1 голос
/ 12 августа 2010

Я пытаюсь создать базовый стробоскоп в браузере, используя элемент canvas.Я ожидаю, что setInterval продолжит вызывать функцию changeBG, чтобы изменить цвет фона на случайный.Эта функция прекрасно работает сама по себе, но не при вызове setInterval.Я попытался вытащить эту страницу в firebug, и она сказала мне, что цвета не определены.Вот проблемный код.

<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, поэтому любое понимание того, что когда-либо будет высоко ценится

Ответы [ 4 ]

6 голосов
/ 12 августа 2010

Ваш код работал бы, если бы вы не передавали строку в setInterval. Поскольку он находится в строке, он не может создать замыкание для переменных, которые вы пытаетесь использовать.

Попробуйте вместо этого:

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

Используя этот метод, вы передаете анонимную функцию в setInterval. Эта функция будет вызываться один раз за интервал, который в данном примере составляет 1000 миллисекунд.

Функция может использовать переменные colors, ctx и canvas, поскольку они существуют в области, в которой функция объявлена. Это создает замыкание, так что эти переменные все еще существуют (что касается нашей анонимной функции), когда она вызывается снова и снова.

Пока вы, вероятно, можете просто использовать этот код. Для дальнейшего понимания я предлагаю исследовать анонимные функции и замыкания.

0 голосов
/ 12 августа 2010

Вы можете передать непосредственно функцию, вместо строки для оценки, как

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

Удачи, провоцирующей эпилепсию кому-либо

0 голосов
/ 12 августа 2010

Основная проблема заключается в переменной области, когда выполняется код интервала, цвета и другие переменные не находятся в области действия.

Попробуйте это:

<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>
0 голосов
/ 12 августа 2010

Попробуйте это ОБНОВЛЕНО setInterval(function(){changeBG(colors,ctx,canvas)}, 1000);

...