下面的代码应该在它所在的画布中的工具提示处创建10x10彩色框,在灰色背景上在红色和蓝色之间交替。我希望每个画布仅在画布内时才响应鼠标。下面的代码制作了4个方形灰色画布,但是当鼠标位于最左边的画布上时,最右边的画布上会出现彩色框。没有其他画布可以工作。
所以这是我的两个问题。
<!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>
答案 0 :(得分: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>