从具有事件侦听器的对象调用函数

Calling function from an object with event listener

本文关键字:对象 调用 函数 侦听器 事件      更新时间:2023-09-26

我有一个这样的视图模型:

CANVAS = getElementById...
RemixView = function(attrs) {
     this.model = attrs.model;
     this.dragging = false;
     this.init();
};
RemixView.prototype = {
    init: function() {
        CANVAS.addEventListener("click", this.handleClick);
    },
    handleClick: function(ev) {
        var obj = this.getHoveredObject(ev);
    },
    getHoveredObject: function(ev) {}
    ...
    ...
}
rv = new RemixView()

问题是我触发 clickHandler 事件时,此对象等于 CANVAS 对象,而不是 RemixView。所以我收到一个错误,说:

this.getHoveredObject 不是一个函数

正确的

方法是什么?

通常的方法是对回调使用一个简单的闭包,并在闭包可以引用的局部变量中捕获适当的this值:

RemixView.prototype = {
    init: function(this) {
        var _this = this;
        CANVAS.addEventListener("click", function(ev) {
            return _this.handleClick(ev);
        });
    },
    //...
};

您还可以使用 Function.prototype.bind 创建一个绑定函数(如 user123444555621 所做的):

RemixView.prototype = {
    init: function(this) {
        CANVAS.addEventListener("click", this.handleClick.bind(this));
    },
    //...
};

或者,如果你想使用 ES6,你可以使用箭头函数:

RemixView.prototype = {
    init: function(this) {
        CANVAS.addEventListener("click", ev => this.handleClick(ev));
    },
    //...
};

你想要绑定处理程序函数:

CANVAS.addEventListener("click", this.handleClick.bind(this));

请注意,这可能不适用于较旧的浏览器,但有适用于这些浏览器的 polyfill。

使prototype成为一个函数。

RemixView.prototype = function () {
    init: function() {
        CANVAS.addEventListener("click", this.handleClick);
    },
    handleClick: function(ev) {
        var obj = this.getHoveredObject(ev);
    } ///...
//...
}