使用p5js创建多个可点击的Divs

时间:2018-08-01 00:46:25

标签: javascript html processing p5.js

编辑:我想通了。我只是走了一条完全不同的路线,制作了一个Button类,并在我的实际画布上使用矩形来表示它们。

我试图在p5js中以编程方式使多个可单击按钮,但我陷入了一个问题。所有的div都将被创建,显示并具有正确的HTML关联,但是无论单击哪个,都仅会诱导最后一个按钮的功能。

这是一张照片: rainbow buttons and a blank canvas

这些是我右边的按钮,但是无论您单击何处,选择的颜色始终是底部的紫色。

这是我的代码:

for (var i = 0; i < colorCodes.length ; i++){
    var div = createDiv(str(i));
    div.parent('control-holder');
    div.style('background-color', colorCodes[i]);
    div.style('height', '40px');
    div.mousePressed(function(){
        console.log(div.html()); //always prints 7
        changeColor(int(div.html()));
    });
    buttons.push(div);
}

非常感谢您的帮助,我不明白为什么它不起作用。

1 个答案:

答案 0 :(得分:1)

这是一个常见的JavaScript陷阱。

使用var关键字时,您创建的变量具有功能范围,这意味着变量(在您的情况下为i变量)保持其值直到函数结束,直到循环结束。考虑以下代码:

for(var i = 0; i < 10; i++){
    console.log('i: ' + i);
}

console.log('final i: ' + i);

此代码将在循环中打印出0-9,然后在循环退出后打印出10。

现在,让我们稍微更改一下代码:

for(var i = 0; i < 10; i++){
    setTimeout(function(){
        console.log('i: ' + i);
    }, 1000);
}

console.log('final i: ' + i);

现在,循环将设置超时回调。此代码将首先打印出final i: 10,然后将打印出i: 10 10次。这是因为在{strong>之前调用回调函数之前发生了console.log('final i: ' + i);行。并且由于该变量具有函数作用域,因此它将使用它给出的最后一个值。这是另一个示例:

var i = 42;

setTimeout(function() {
    console.log('i: ' + i);
}, 1000);

i = 37;

您可能希望此代码能打印出42,但同样,此代码运行后,在 之后会调用回调函数,因此在被调用时i37

无论如何,回到您的代码。希望上面的示例向您展示代码中的情况:var关键字创建了一个函数范围的变量,这意味着在调用mousePressed回调时,该变量将保留其最后一个设置值。 / p>

传统上,解决此问题的方法是通过另一个函数调用:

for (var i = 0; i < 10; i++) {
    callSetTimeout(i);
}

console.log('final i: ' + i);

function callSetTimeout(i) {
    setTimeout(function() {
        console.log('i: ' + i);
    }, 1000);
}

但是从JavaScript 6开始,您可以使用let关键字代替var

for(let i = 0; i < 10; i++){
    setTimeout(function(){
        console.log('i: ' + i);
    }, 1000);
}

这将为您的变量提供 block作用域,这意味着该变量仅在for循环范围内。结果,循环的每次迭代都会得到自己的副本,您的函数现在将按预期的方式工作。