Проблема с setInterval и неопределенными аргументами

Я пытаюсь создать базовый стробоскоп в браузере, используя элемент 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 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

<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>

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

Другие вопросы по тегам