【问题标题】:Get "event" object within the immediately executed function?在立即执行的函数中获取“事件”对象?
【发布时间】:2010-09-22 13:39:33
【问题描述】:

我以这种方式使用事件委托:

elWraper.onclick = (function(){
    //how to get here "event" object
    e = e || window.event;
    var t = e.target || e.srcElement;

    //event handler
    return function(){
        //manipulations with "t" variable
    }
})();

如何在立即执行的函数中获取“事件”对象?

【问题讨论】:

  • 你的目标是什么?您正在调用一个函数,使用未定义的变量e(因此,脚本执行将因错误而停止)
  • 你为什么要这样做而不是addEventListener

标签: javascript javascript-events event-handling


【解决方案1】:
elWraper.onclick = (function(){
    // misc stuff here    

    //event handler
    return function(e){
        e = e || window.event;
        var t = e.target || e.srcElement;
        //manipulations with "t" variable
    }
})();

在符合标准的浏览器中,事件对象是传递给回调函数的第一个参数。在 IE 中,它是一个全局变量(这是 e = e || window.event 试图确定的)。因此,immediately executed function 返回的函数应该接受声明为它的第一个(通常也是唯一的)参数的事件对象。


澄清

由于人们想知道(并且可能他们想知道为什么 OP 接受了这个答案),所以从 OP 的问题中并不清楚它的用途。一种是创建一个变量的闭包来跟踪某些东西:

/* Count number of clicks,
 * WITHOUT USING GLOBAL VARS!
 */
el.onclick = (function(){
    var counter = 0;
    return function(e){
      e = e || window.event;
      var t = e.target || e.srcElement;
      counter ++;
      alert('detected '+counter+' clicks!');
      // do stuff with t or e ...
    }
})();

另外,这是在循环中分配事件处理程序的经典方式:

/* Use double closure to break closure in loop!
 */
for (var i=0; i<stuff.length; i++) {
    var el = stuff[i];
    el.onclick = (function(x){
        return function(e){
          e = e || window.event;
          var t = e.target || e.srcElement;
          alert(x);
          // do stuff with t or e ...
        }
    })(i);
}

或者,也许 OP 只是认为他可以“缓存”事件对象并错误地认为他可以使用它来做到这一点。在这种情况下,阅读我的解释(而不仅仅是代码)应该会让读者明白为什么这是一个坏主意。

【讨论】:

  • 我不明白。为什么不只是elWraper.onclick = function(e){...}
  • 我也没有(来自示例代码)。但这就是 OP 要问的问题,所以这就是我要回答的问题。也许他正在做一些事情,上面写着//misc stuff here,比如为一些变量创建一个闭包,让它们表现得像静态变量或其他东西。这有一些用途(这基本上是您在循环中分配事件处理程序的方式),但仅通过阅读 OP 的原始代码并不清楚。
  • 在这个例子中,处理程序不使用 i 变量,但如果使用了,它在所有处理程序中都是相同的(循环结束后 i 的值)。这将是为每个处理程序单独设置 i 的唯一方法。
【解决方案2】:
elWraper.onclick = function (e) {
  //how to get here "event" object
  e = e || window.event;
  var t = e.target || e.srcElement;
  //manipulations with "t" variable
};

【讨论】:

  • 不过,这不是一个“立即执行”的功能。它在函数定义的末尾缺少 () 运算符。
  • @Alex JL:是的,但是首先在这里有一个“立即执行”的功能有什么意义呢?这只是无关的 AFAICT。
【解决方案3】:

根据您的问题,我认为 slebetman 的回答是正确的。但是,我不明白你在做什么。如果你试图抽象浏览器的事件差异,你可以使用类似这样的东西。

function createHandler( context, handler ) {
  return function (e) {    
    e = e || window.event;
    var t = e.target || e.srcElement;
    handler.call (context || window, e, t);
  }
}

那么你就可以像这样使用它了

div.onclick = createHandler(div, function(e, t){
   alert ("actual clicked target is " +  t.id);
   alert ("handler was set on node " + this.id);
});

请注意,您可以将任何内容作为上下文传递(处理程序中的“this”关键字)

很高兴知道这些东西,但是 jquery 或许多其他库已经为你做这件事,而且它比你的代码经过更多的测试,并且它比这个小函数处理更多的浏览器差异。但是,如果这就是你所需要的,这确实可以让代码变得臃肿。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 2017-05-20
    • 1970-01-01
    • 2021-08-23
    • 2011-10-04
    相关资源
    最近更新 更多