2017-07-07 5 views
0

以下のコードは、灰色の背景に赤と青が交互に現れるキャンバスのツールチップに10x10色のボックスを作成することになっています。それぞれのキャンバスがキャンバス内にあるときだけマウスに反応するようにしたい。下のコードは4つの正方形の灰色のキャンバスを作成しますが、マウスが左端のキャンバスの上にあるときは、最も右側のキャンバスに色付きのボックスが表示されます。他のキャンバスは動作しません。javascriptで複数のクリックレスポンスキャンバスを作成するにはどうすればよいですか?

ここに私の2つの質問があります。

  1. なぜ1つのキャンバスがアクティブになっていますか?
  2. なぜボックスが間違ったキャンバスに表示されるのですか?

<!DOCTYPE html> 
 
<html> 
 
<body> 
 
<canvas id="c0" width="201" height="201"></canvas> 
 
<canvas id="c1" width="201" height="201"></canvas> 
 
<canvas id="c2" width="201" height="201"></canvas> 
 
<canvas id="c3" width="201" height="201"></canvas> 
 

 
<script> 
 
var colorno = ["#F77", "#077"]; 
 
var the = { 'c0': {}, 'c1': {}, 'c2': {}, 'c3': {} }; 
 
var box = 10; 
 
var workings = function(name) { 
 
    instance = the[name]; 
 
    instance.name = name; 
 
    canvas = instance.canvas = document.getElementById(instance.name); 
 
    instance.context = canvas.getContext("2d"); 
 
    instance.index = 0; 
 
    instance.context.fillStyle = "#777"; 
 
    instance.context.fillRect(0, 0, canvas.width, canvas.height); 
 
    scale = (canvas.width - box)/canvas.width; 
 
    canvas.addEventListener("click", function(e) { 
 
     instance.context.fillStyle = colorno[++instance.index&1]; 
 
     instance.context.fillRect(scale*e.x-box, scale*e.y-box, box, box); 
 
    }, true); 
 
}; 
 
for (var key in the) workings(key); 
 
</script> 
 

 
</body> 
 
</html>

答えて

1

あなたはそれがグローバルスコープで定義されていることを引き起こして、変数instanceを宣言していなかったからです。 instanceはあなたのforループによって上書きされ続けるので、すべての4つのハンドラでは、instance変数はすべて同じオブジェクトを指しています。クロージャーで変数を正しく宣言することは非常に重要です。ここで

var instance = value;  // declare function-scoped variable 
let instance = value;  // declare block-scoped variable 
function workings(args){} // declare a function 

固定されているコードのバージョンです:

<!DOCTYPE html> 
 
<html> 
 
<body> 
 
<canvas id="c0" width="201" height="201"></canvas> 
 
<canvas id="c1" width="201" height="201"></canvas> 
 
<canvas id="c2" width="201" height="201"></canvas> 
 
<canvas id="c3" width="201" height="201"></canvas> 
 

 
<script> 
 
var colorno = ["#F77", "#077"]; 
 
var the = { 'c0': {}, 'c1': {}, 'c2': {}, 'c3': {} }; 
 
var box = 10; 
 

 
// declare function 
 
function workings(name) { 
 
    // declare variables 
 
    var instance = the[name]; 
 
    var canvas = instance.canvas = document.getElementById(name); 
 
    // assign values 
 
    instance.name = name; 
 
    instance.context = canvas.getContext("2d"); 
 
    instance.index = 0; 
 
    instance.context.fillStyle = "#777"; 
 
    instance.context.fillRect(0, 0, canvas.width, canvas.height); 
 

 
    // attach click listener 
 
    canvas.addEventListener("click", function(e) { 
 
     instance.context.fillStyle = colorno[++instance.index&1]; 
 
     instance.context.fillRect(
 
      // calculate correct coordinates 
 
      e.pageX - canvas.offsetLeft - box/2, 
 
      e.pageY - canvas.offsetTop - box/2, 
 
      box, box); 
 
    }, true); 
 
}; 
 

 
// invoke function 
 
for (var key in the) workings(key); 
 
</script> 
 

 
</body> 
 
</html>

+0

PERFECTは!あなたの説明はうまく簡潔かつ明確でした。ありがとうございました。 – jlettvin

関連する問題