将事件处理程序应用于变量

时间:2013-10-19 20:46:53

标签: javascript jquery events

有没有办法将事件处理程序应用于变量,还是需要使用隐藏的输入等完成?我有一个变量被设置:

var c = document.getElementById('myCanvas');
c.myVar = 17;

我想为它设置一个事件处理程序,以防它发生变化,保存创建和更改的多余隐藏输入,并且通常只是简化我的代码。

谢谢!

2 个答案:

答案 0 :(得分:1)

如果要挂钩DOM元素属性的更改,可能需要查看DOM Mutation events。虽然感觉有点过分 - 我只是在函数中包含对该属性的所有访问,然后在该函数内调用我喜欢的任何内容。您只需确保始终使用该功能来访问该属性。

答案 1 :(得分:0)

为了说明你想要的东西你可以通过调用所需的函数来定义对象属性的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;
}

FIDDLE

注意:上述解决方案用于说明回答特定问题的要点。它不能很好地解决对自绘对象的需求。这是因为我从两个地方调用绘画(每当x或y改变时)。如果你总是在改变x和y,你会做两次绘画。更好的方法是更改​​x,更改y和所需的任何其他状态更改,然后在对象上调用paint方法以使其自行绘制。

这确实可以很好地说明这种模型的问题,因此它有助于显示在这样做时可以进入的陷阱。因此,我已将代码保留为此注释。

我已经完成了这个新版本,它显示了我认为在以下代码中执行此操作的更好方法。只有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);

FIDDLE