如何将事件侦听器回调设置为成员函数
How to set an event listener callback to a member function
我正在为画布对象编写一个小的面向对象的包装器,并且我想将一些按钮回调设置为实际的函数成员,而不是全局作用域的函数(这样我就可以将上下文对象引用为成员)。
function CanvasManager(canvasId) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', this.handleImage, false);
var lineNumberField = document.getElementById('linenumber');
lineNumberField.addEventListener('change', this.onLineNumberChange, false);
}
function handleImage = function(e) {
var reader = new FileReader();
var that = this;
reader.onload = function(event){
var img = new Image();
img.onload = function(){
that.canvas.width = img.width;
that.canvas.height = img.height;
that.ctx.drawImage(img,0,0);
};
img.src = event.target.result;
};
reader.readAsDataURL(e.target.files[0]);
};
在html:
内嵌脚本中调用。<div id="canvas-container" style="display:none;">
<canvas id="imageCanvas"></canvas>
</div>
...
<script lang="javascript">new CanvasManager('imageCanvas');</script>
这不起作用,因为在handleImage
回调中,"This"不是指CanvasManager
实例,而是指imageLoader
实例,这使我非常困惑。
我在这里做错了什么?
抱歉的评论-实际上,如果问题是在第二个方法内,我已经误解了你所描述的问题。
正如其他人所暗示的那样,事件侦听器将以window
作为this
对象调用该函数。别担心,即使作为JS专家,我也同意这没有多大意义。
虽然您可以简单地将所有内容放在闭包中,并将this
放入常量var
(即me
或self
),但我的偏好是自定义对函数的调用,以始终具有特定的this
引用。你可以这样做:
imageLoader.addEventListener('change', this.handleImage.bind(this), false);
bind()是一个相对较新的JavaScript函数,它为您提供了一个新方法,表示原始方法,但使用特定的this
上下文调用。一些JavaScript库具有与旧浏览器兼容的等效库,例如Dojo的"hitch"。但是,由于您的代码无论如何都涉及<canvas>
,因此您应该基本上可以满足兼容性。
try this
function CanvasManager(canvasId) {
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext('2d');
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', this.handleImage, false);
var lineNumberField = document.getElementById('linenumber');
lineNumberField.addEventListener('change', this.onLineNumberChange, false);
var self = this; // keep CanvasManager instance
this.onLineNumberChange = function(){
};
this.handleImage = function(){
console.log(self); // use CanvasManager instance
}
}
看起来你的函数handleImage在你试图使用的主函数(或类)之外。我将按如下方式更新代码:
function CanvasManager(canvasId) {
var me = this;
me.canvas = document.getElementById(canvasId);
me.ctx = me.canvas.getContext('2d');
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', me.handleImage, false);
var lineNumberField = document.getElementById('linenumber');
lineNumberField.addEventListener('change', me.onLineNumberChange, false);
me.handleImage = function(e) {
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(){
me.canvas.width = img.width;
me.canvas.height = img.height;
me.ctx.drawImage(img, 0, 0);
};
img.src = event.target.result;
};
reader.readAsDataURL(e.target.files[0]);
}
}
通过将handleImage移动到函数内部,它现在处于类的作用域中。此外,通过在方法开始时使用me = this,可以始终访问它的类实例,因为this将默认引用触发它的事件的对象。
相关文章:
- 如何设置html元素填充的动画
- 对象'未设置的数据成员值
- Knockout JS未将所有成员设置为可观察
- 在 Nodejs 中设置 Prototype 类的成员变量
- ie8 设置样式时找不到成员
- Javascript:尝试将函数设置为数组中对象的成员
- 特定成员组件的设置值
- 访问功能内的成员/从外部设置成员
- 路由加载时运行成员控制器函数以设置控制复选框的属性
- 将类中HTMLElement成员的onclick属性设置为同一类的方法
- 设置iframe's window.external成员通过javascript
- 无法设置未定义成员的属性
- 当为空时,设置JavaScript对象成员的默认值
- 从返回的承诺中设置成员变量
- 通过回调设置object的成员奇怪地失败了
- JavaScript如何从回调函数中设置成员变量
- 如何将事件侦听器回调设置为成员函数
- 将数组成员设置为 null 而不是 “”
- JQuery - 在对象列表中搜索将特定成员变量设置为值的对象
- 当从渲染助手设置时,把手模板不尊重视图成员