Проблема с 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);