有没有办法将事件处理程序应用于变量,或者是否需要使用隐藏输入等来完成?我已经设置了一个变量:
var c = document.getElementById('myCanvas');
c.myVar = 17;
而且我想为它设置一个事件处理程序,以防它发生变化,保存创建和更改的多余隐藏输入,并且通常简化我的代码。
谢谢!
有没有办法将事件处理程序应用于变量,或者是否需要使用隐藏输入等来完成?我已经设置了一个变量:
var c = document.getElementById('myCanvas');
c.myVar = 17;
而且我想为它设置一个事件处理程序,以防它发生变化,保存创建和更改的多余隐藏输入,并且通常简化我的代码。
谢谢!
如果您想挂钩 DOM 元素的属性更改,您可能需要查看DOM Mutation events。不过感觉有点矫枉过正——我只需将对该属性的所有访问封装在一个函数中,然后从该函数内部调用我喜欢的任何内容。您只需确保始终使用该函数来访问该属性。
为了说明您想要什么,您可以通过调用所需的函数在对象属性上定义 getter 和 setter:
HTML:
<canvas id="myCanvas" class="border"></canvas>
JavaScript:
var x = 0,
y = 0,
c = document.getElementById('myCanvas'),
ctx = c.getContext('2d'),
WIDTH = c.width,
HEIGHT = c.height,
paint = function () {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
ctx.beginPath();
ctx.rect(x, y, 6, 6);
ctx.closePath();
ctx.fill();
};
Object.defineProperty(c, 'x', {
get: function () {
return x;
},
set: function (value) {
x = value;
paint();
}
});
Object.defineProperty(c, 'y', {
get: function () {
return y;
},
set: function (value) {
y = value;
paint();
}
});
window.setInterval(function () {
var dx = Math.round(Math.random() * 6) - 3,
dy = Math.round(Math.random() * 6) - 3;
if (c.x + dx > 0 && c.x + dx < c.width) {
c.x += dx;
}
if (c.y + dy > 0 && c.y + dy < c.height) {
c.y += dy;
}
}, 20);
CSS:
canvas.border {
border-style: solid;
border-color: 0;
}
注意:上述解决方案用于说明回答特定问题的要点。它不能很好地解决对自绘对象的渴望。这是因为我从两个地方调用paint(每当x 或y 改变时)。如果你总是改变 x 和 y,你就画了两次。更好的方法是更改 x、更改 y 和任何其他所需的状态更改,然后调用对象上的绘制方法以使其自身绘制。
这确实很好地说明了这种模型的问题,因此它在展示以这种方式做事时可能陷入的陷阱是有价值的。因此,我将代码保留在此注释中。
我已经完成了一个新版本,显示了我认为在以下代码中执行此操作的更好方法。只有 JavaScript 发生了变化:
JavaScript:
function DrunkBox(x, y) {
'use strict';
var c = document.getElementById('myCanvas'),
ctx = c.getContext('2d');
this.width = c.width;
this.height = c.height;
this.x = x,
this.y = y;
this.paint = function () {
ctx.clearRect(0, 0, this.width, this.height);
ctx.beginPath();
ctx.rect(this.x, this.y, 6, 6);
ctx.closePath();
ctx.fill();
};
}
var db = new DrunkBox(50, 30);
window.setInterval(function () {
var dx = Math.round(Math.random() * 6) - 3,
dy = Math.round(Math.random() * 6) - 3;
if (db.x + dx > 0 && db.x + dx < db.width) {
db.x += dx;
}
if (db.y + dy > 0 && db.y + dy < db.height) {
db.y += dy;
}
db.paint();
}, 20);