JavaScript Canvas 对更改事件不起作用

JavaScript Canvas does not work onchange event

如果我删除这部分,以下代码有效:

checkboxPencil.onchange = function() {
    if(checkboxPencil.checked) {

如果可行,我可以在我的canvas上画画,否则我不能。

因为我想在 onchange 上做一些事情,所以我需要用 onchange 事件包装我的函数,并检查是否选中了复选框。

但我不明白为什么这不适用于上面的两行。 我在 Chrome 开发者控制台中没有收到任何错误。

如果我删除上面的两行,我的代码仍然有效,但如果我添加它们,它就不起作用,我不明白为什么。

完整代码:

if(window.addEventListener) {
    window.addEventListener('load', function () {

    ...

    // Initialization sequence.
    function init () {

        canvas = document.getElementById('imageView');


        tool = new tool_pencil();

        canvas.addEventListener('mousedown', ev_canvas, false);
        canvas.addEventListener('mousemove', ev_canvas, false);
        canvas.addEventListener('mouseup', ev_canvas, false);
    }

    function tool_pencil() {

        var tool = this;
        this.started = false;

        checkboxPencil.onchange = function() {
            if(checkboxPencil.checked) {
                console.log("Pencil checked");

                this.mousedown = function (ev) {
                    context.beginPath();
                    context.moveTo(ev._x, ev._y);
                    tool.started = true;
                };

                this.mousemove = function (ev) {
                    if (tool.started) {
                        context.lineTo(ev._x, ev._y);
                        context.stroke();
                    }
                };

                this.mouseup = function (ev) {
                    if (tool.started) {
                        tool.mousemove(ev);
                        tool.started = false;
                    }
                };
            } else {
                console.log("Pencil not checked");
            }
        }
    }

出现此问题是因为,在您将它们添加到 canvas 时,这些鼠标事件侦听器回调函数尚未初始化。

在 canvas.

上绘图之前,您应该检查复选框是否被选中

window.addEventListener('load', init);

function init() {
    canvas = document.getElementById('imageView');
    checkboxPencil = document.getElementById('checkboxPencil');
    context = canvas.getContext("2d");
    tool = new tool_pencil();
    canvas.addEventListener('mousedown', tool.mousedown, false);
    canvas.addEventListener('mousemove', tool.mousemove, false);
    canvas.addEventListener('mouseup', tool.mouseup, false);
}

function tool_pencil() {
    this.started = false;
    this.mousedown = function(ev) {
        if (checkboxPencil.checked) {
            context.beginPath();
            context.moveTo(ev.offsetX, ev.offsetY);
            this.started = true;
        }
    };
    this.mousemove = function(ev) {
        canvas.style.cursor = 'default';
        if (this.started && checkboxPencil.checked) {
            context.lineTo(ev.offsetX, ev.offsetY);
            context.stroke();
        }
    };
    this.mouseup = function(ev) {
        if (this.started && checkboxPencil.checked) {
            this.started = false;
        }
    };
}
canvas {
  border: 1px solid black;
}
<canvas id="imageView" width="300" height="300"></canvas>
<input type="checkbox" id="checkboxPencil">Pencil

我没有足够的上下文来 运行 你的代码,但我想我至少可以猜出部分问题...

我假设 checkboxPencil 已被初始化为 var checkboxPencil = document.getElementById('my_checkbox_element') 或类似的。为此,需要在 window.onload 代码中,在您省略的部分中声明 checkboxPencil

我还假设 tool 是在那个省略的部分或全局声明的。否则 tool = new tool_pencil() 行什么都不做。

而且,我假设 ev_canvas 是一个调用 tool 对象的相关 mousedown/mouseup/mousemove 方法的函数。

如果所有这些假设都是正确的,最明显的问题是您将 mousedown 等函数附加到错误的对象。因为您是在 HTML 复选框元素的 onchange 处理程序中进行分配,所以当该代码 运行s、this 将引用复选框元素时,不是封闭的tool_pencil对象。我相信你想换行

this.mousedown = function (ev) {

(等)到

tool.mousedown = function (ev) {

在此上下文中,tool 通过闭包引用 tool_pencil 函数的局部变量 tool

另一个问题是它看起来不像是定义了context。可能您想在代码的省略部分声明它,然后在初始化 canvas 后立即添加行

context = canvas.getContext("2d");