2017-04-04 93 views
0

下面的代码工作。JavaScript的画布不起作用onchange事件

因为我想做一些onchange我需要包装我的函数与onchange事件并检查是否复选框被选中。

但我不明白为什么这不符合上述2行。 我在Chrome开发者控制台中没有收到任何错误。

再次我的代码工作,如果我删除上面的2行,但它不起作用,如果我添加它们,我不明白为什么。

全码:

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"); 
      } 
     } 
    } 

回答

1

问题发生,因为这些鼠标事件侦听器回调函数没有被你将它们添加到画布时被初始化。

在绘制画布之前,您应该检查复选框是否已勾选。

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

+0

美丽非常感谢你喜欢这个'在window.onload = init;方法的'代替这个:'if(window.addEventListener){ window.addEventListener('load',function(){'如果是的话为什么?:) – Micheasl

+0

@Micheasl虽然,我不介意使用它们中的任何一个(只要它是肯定的清楚正在做什么),我更喜欢'addEventListener'。你可以参考[这里](http://stackoverflow.com/a/6348533/7750640)以获得更好的解释:) –

0

没有足够的背景下,我来运行你的代码,但我想我可以猜到了问题的至少一部分......

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

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

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

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

this.mousedown = function (ev) {

(等)更改为

tool.mousedown = function (ev) {

在此背景下,tool指的是局部变量的tool_pencil功能tool,通过关闭。

另一个问题是,它看起来不像context被定义。也许你要声明它在你的代码的省略部分,然后你初始化canvas之后,添加行

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