如何将事件侦听器回调设置为成员函数

Fab*_*och 1 html javascript canvas

我正在围绕画布对象编写一个面向对象的小包装器,我想为实际函数成员设置一些按钮回调,而不是全局范围的函数(这样我可以将上下文对象称为成员)。

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]);     
};
Run Code Online (Sandbox Code Playgroud)

这在 html 的内联脚本中调用:

<div id="canvas-container" style="display:none;">
    <canvas id="imageCanvas"></canvas>
</div>
    ...
<script lang="javascript">new CanvasManager('imageCanvas');</script>
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为在handleImage回调中,“this”不是指CanvasManager实例,而是imageLoader实例,这让我非常困惑。

我在这里做错了什么?

Kat*_*314 6

很抱歉发表评论 - 实际上,如果问题在第二种方法中,我会像您描述的那样误解该问题。

正如其他人暗示的那样,事件侦听器将调用该函数window作为this对象。别担心,即使作为 JS 大师,我也同意这没有多大意义。

虽然您可以简单地将所有内容放入闭包中并放入this一个常量var(即meself)中,但我的偏好是自定义对函数的调用以始终具有特定的this引用。你可以这样做:

imageLoader.addEventListener('change', this.handleImage.bind(this), false);
Run Code Online (Sandbox Code Playgroud)

bind() 是一个相对较新的 JavaScript 函数,它为您提供了一个新方法,表示原始方法,但使用特定this上下文调用。一些 JavaScript 库具有与旧浏览器兼容的等效项,例如 Dojo 的“hitch”。但是,由于您的代码<canvas>无论如何都涉及 a ,因此您的兼容性应该基本没问题。