【问题标题】:How to make "this" not refer to the element an event was called on?如何使“this”不引用事件被调用的元素?
【发布时间】:2012-07-01 19:45:35
【问题描述】:

我知道 Javascript 中没有类,为了方便,我将构造函数称为类。

我正在用 Javascript 创建一个名为 InputHandler 的类。它有一个名为onMouseDown 的方法,并将其注册为一个事件处理程序,如下所示:

Irenic.InputHandler.prototype.attach = function()
{
    var inputHandler = this; //Get the instance of InputHandler

    document.addEventListener("keydown", inputHandler.onKeyDown, false); //Concentrate on this, but the question applies to all of these.
    document.addEventListener("keyup", inputHandler.onKeyUp, false);
    document.addEventListener("mousemove", inputHandler.onMouseMove, false);
    document.addEventListener("mouseup", inputHandler.onMouseUp, false);
    document.addEventListener("mousedown", inputHandler.onMouseDown, false);
}

Irenic 是我正在构建的引擎的名称,它也是一个包含所有这些类的全局对象。)

inputHandler.onMouseDown 方法如下所示:

Irenic.InputHandler.prototype.onMouseDown = 函数(事件) { var inputHandler = this; //这可悲的是指的是文档,而不是 InputHandler 的实例

console.log(inputHandler); //Logs #document

if (event.button == 0)
{
    inputHandler.mouse.lmb = true;
}

if (event.button == 1)
{
    inputHandler.mouse.wheel = true;
}

if (event.button == 2)
{
    inputHandler.mouse.rmb = true;
}

}

正如我在 cmets 中所说,this 关键字指的是触发事件的元素。我显然不希望这样:那么如何让它引用InputLoader 的实例?

【问题讨论】:

  • 为什么不直接使用闭包,而这个构造:(())()

标签: javascript events this


【解决方案1】:

使用Function.prototype.bind 锁定函数的上下文:

inputHandler.onKeyDown.bind(inputHandler)

PS。使用switch,或至少else if,而不是多个if 构造。只有其中一个是真的。

【讨论】:

  • 这个我不太清楚,但是IE不是有很多问题吗?
  • @AdnanShammout addEventListener 无论如何都会有很多 IE 问题
  • @AdnanShammout IE 不支持 addEventListener 之前的 v9。所有现代浏览器都支持.bind,MDN 提供了polyfill 来支持旧版浏览器。
  • 是的,我可以在 3 秒内从头顶写下这个绑定子集:function bind(fn,ctx){ return function(){return fn.apply(ctx, arguments);}; }
【解决方案2】:

在您的构造函数中,将实例的方法绑定到该实例:

function InputHandler() {
    this.onKeyDown = this.onKeyDown.bind(this);
    this.onKeyUp = this.onKeyUp.bind(this);
    this.onMouseMove = this.onMouseMove.bind(this);
    this.onMouseUp = this.onMouseUp.bind(this);
    this.onMouseDown = this.onMouseDown.bind(this);
}

这样,实例一经构建就准备就绪。

Function#bind

【讨论】:

    【解决方案3】:

    我认为 bind 不适用于 IE

    document.addEventListener("keydown", function (ev) { return inputHandler.onKeyDown(ev); }, false)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 2020-07-15
      • 2013-11-06
      • 1970-01-01
      • 2011-08-07
      相关资源
      最近更新 更多