[英]Update or Change or Remove/Reset Javascript event listener
好的,所以我正在开发一个小的html5 canvas绘图库,但是我遇到了一个小问题,这是代码(下面的小提琴):
var drawr = {
init: function (canvas_id, canvasWidth, canvasHeight) { //height & width are optional
this.canvas_id = document.getElementById(canvas_id);
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
this.context = this.canvas_id.getContext('2d');
if (canvasWidth) {
this.canvas_id.width = canvasWidth;
}
if (canvasHeight) {
this.canvas_id.height = canvasHeight;
}
},
//magic line drawing function
ctx: function (a, b, x, y, dLineColor, dLineWidth) { //lineWidth & lineColor are optional; defaults are 1px & 'black'
this.context.lineJoin = 'round';
this.context.beginPath();
this.context.moveTo(a, b);
this.context.lineTo(x, y);
this.context.closePath();
this.context.strokeStyle = dLineColor;
this.context.lineWidth = dLineWidth;
this.context.stroke();
},
//destroy event handlers to prevent drawing
destroy: function () {
//destroy event handlers
},
draw: function (lineColor, lineWidth) {
//create some utilities for draw function to use
var localPen = {};
var drawing = false;
var canvasPos = {
x: this.canvas_id.offsetLeft,
y: this.canvas_id.offsetTop
}
//initiate event handlers
this.canvas_id.addEventListener('mousedown', addDraw, false);
function addDraw(e) {
drawing = true;
console.log(drawing);
localPen.x = e.pageX - canvasPos.x;
localPen.y = e.pageY - canvasPos.y;
};
this.canvas_id.addEventListener('mousemove', function (e) {
var drawTo = {
x: e.pageX - canvasPos.x,
y: e.pageY - canvasPos.y
}
if (drawing) {
drawr.ctx(localPen.x, localPen.y, drawTo.x, drawTo.y, lineColor, lineWidth);
}
localPen.x = drawTo.x;
localPen.y = drawTo.y;
});
this.canvas_id.addEventListener('mouseup', function (e) {
drawing = false;
});
this.canvas_id.addEventListener('mouseleave', function (e) {
drawing = false;
});
}
}
drawr.init('my_canvas');
drawr.draw('red', 10);
drawr.draw('blue', 5);
我要在这里完成的工作是:当我调用drawr.draw();
第二个(或第三个,等等)以覆盖先前的功能。 我应该怎么做? 正如您在我的小提琴中看到的那样,每个实例同时运行。
随意编辑,更新,删除,对我大喊不好的代码,等等。
仅当为该事件类型指定的处理函数严格相等时,对addEventListener
的调用将覆盖前一个,或对removeEventListener
的调用将删除侦听removeEventListener
。 匿名函数即使在词法上相同,也将不等于在单独执行该方法期间创建的第二个匿名函数。
这是一个想法:将您的处理程序定义为闭包中的单独函数,如下所示:
obj = function() {
function handler() { /* handle the click; "this" is the element */ }
return {
draw: function() {
this.elt.addEventListener('click', handler);
//draw a bunch of stuff
},
undraw: function() {
this.elt.removeEventListener('click', handler);
//undraw a bunch of stuff
}
};
}();
现在,由于handler
始终严格等于其自身,因此removeEventListener
将成功删除处理程序。 或者,第二个addEventListener
将不执行任何操作(只需将当前处理程序留在原处)。
但是, handler
无法访问该对象的this
; 它将使用事件的目标元素作为其this
进行调用。 为了得到对象的this
到这个事件处理,你可能会尝试
this.elt.addEventListener('click', handler.bind(this));
但这将无法完成您想要的操作,因为每次调用该方法时, handler.bind(this)
的值都不同,因此您将再次获得多余的事件处理程序或removeEventListener
,它们均无效。
如果你真的想对象的this
在处理程序,并不能弄清楚如何从事件检索它,你可以初始化的绑定版本handler
在一些init
函数:
obj = {
handler: function(event) { /* handle the click; "this" is the object */ },
draw: function() {
this.elt.addEventListener('click', this.handler);
//draw a bunch of stuff
},
undraw: function() {
this.elt.removeEventListener('click', this.handler);
//undraw a bunch of stuff
},
init: function() {
this.handler = this.handler.bind(this);
return this;
}
}.init();
由于this.handler
始终与其自身相同,因此可以正常工作。
EventListener
解决此问题的一种更优雅的方法是将带有EventListener接口的对象传递给addEventListener
而不是函数,该对象是实现特殊命名的handleEvent
方法的任何对象,该对象可以是'this'对象本身,因此,您可以执行以下操作:
obj = {
handleEvent: function(event) {
// "this" is the object
if (event.type === 'click') {
// do stuff
}
},
draw: function() {
this.elt.addEventListener('click', this);
},
undraw: function() {
this.elt.removeEventListener('click', this);
}
};
请注意, this
已传递给addEventListener
。 换句话说,由于对象本身已实现handleEvent
,因此以对象的形式将其本身作为EventListener
的实例传递。 handleEvent
是对象的完整方法,因此可以完全访问其所有方法和属性,并且由于this
与自身完全相同,因此添加,再次添加和删除行为都可以根据需要进行。
我看不到这种方法使用得太多,但是它可以使事件处理更加简化,尤其是如果在它周围添加一些糖,例如安排单独的方法来处理每种事件类型:
obj = {
handleEvent: function(event) {
return this[event.type](event); // dispatch to method with name of event
},
click: function(event) {
// handle click; "this" is obj
},
draw: function() {
this.elt.addEventListener('click', this);
},
undraw: function() {
this.elt.removeEventListener('click', this);
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.