什么';在JavaScript中,将元素作为第一个参数传递给事件处理程序的最简单方法是什么?

什么';在JavaScript中,将元素作为第一个参数传递给事件处理程序的最简单方法是什么?,javascript,jquery,event-handling,bind,jquery-events,Javascript,Jquery,Event Handling,Bind,Jquery Events,我知道,在事件处理函数中将其值更改为接收事件的元素非常有用。但是,我希望函数总是在应用程序上下文中调用,而不是在元素上下文中调用。这样,我可以将它们用作事件处理程序,也可以以其他方式使用,例如在setTimeout调用中 所以,代码如下: window.app = (function () { var that = { millerTime: function () {}, changeEl: function (el) { el

我知道,在事件处理函数中将其值更改为接收事件的元素非常有用。但是,我希望函数总是在应用程序上下文中调用,而不是在元素上下文中调用。这样,我可以将它们用作事件处理程序,也可以以其他方式使用,例如在
setTimeout
调用中

所以,代码如下:

window.app = (function () {
    var that = {
        millerTime: function () {},
        changeEl: function (el) {
            el = el || this;
            // rest of code...
            that.millerTime();
        }
    };
    return that;
}());
window.app = (function () {
    return {
        millerTime: function () {},
        changeEl: function (el) {
            // rest of code...
            this.millerTime();
        }
    };
}());
可能就是这样:

window.app = (function () {
    var that = {
        millerTime: function () {},
        changeEl: function (el) {
            el = el || this;
            // rest of code...
            that.millerTime();
        }
    };
    return that;
}());
window.app = (function () {
    return {
        millerTime: function () {},
        changeEl: function (el) {
            // rest of code...
            this.millerTime();
        }
    };
}());
第一种方式让我感到困惑。是否有一种简单的方法可以将接收事件的元素作为第一个参数(最好是jQuery包装的元素)传递给我的事件处理函数并在app上下文中调用?假设我使用jQuery绑定了一堆事件处理程序。我不想总是包含匿名函数:

$('body').on('click', function (event) {
    app.changeEl.call(app, $(this), event);  // would be nice to get event too
});
我需要一个单一的功能,将照顾这一切为我。在这一点上,我觉得传递匿名函数是不可能的,但我只是想看看是否有人能找到解决方案

我的尝试是:

function overrideContext (event, fn) {
   if (!(this instanceof HTMLElement) ||
         typeof event === 'undefined'
   ) {
       return overrideContext;
   }

   // at this point we know jQuery called this function // ??
   var el = $(this);

   fn.call(app, el, event);
}

$('body').on('click', overrideContext(undefined, app.changeEl));
使用
Function.prototype.bind
(我是新手),仍然无法获取元素:

window.app = (function () {
    return {
         millerTime: function () {},
         changeEl: function (el) {
            // rest of code...
            console.log(this); // app
            this.millerTime();
         }
    };
}());

function overrideContext (evt, fn) {
    var el = $(this); // $(Window)
    console.log(arguments); // [undefined, app.changeEl, p.Event] 
    fn.call(app, el, event);
}

$('body').on('click', overrideContext.bind(null, undefined, app.changeEl));

使用('click',重写econtext.bind(app.changeEl))相反,它指向我的
app.changeEl
函数,我的参数长度为1,只包含
p.Event
。在这两种情况下,我仍然无法获取元素。

定义这样的函数应该可以满足您的需要:

function wrap(func) {
  // Return the function which is passed to `on()`, which does the hard work.
  return function () {
    // This gets called when the event is fired. Call the handler
    // specified, with it's context set to `window.app`, and pass
    // the jQuery element (`$(this)`) as it's first parameter.
    func.call(window.app, $(this) /*, other parameters (e?)*/);
  }
}
然后你会像这样使用它

$('body').on('click', wrap(app.changeEl));
有关详细信息,请参阅



此外,我建议不要使用这种方法。精通JavaScript的程序员希望上下文在超时和事件处理程序中发生变化。把这个基本原理从它们身上拿走就像我把你丢在撒哈拉沙漠中,没有指南针。

使用道格拉斯·克罗克福德的模块模式(或类似模式)编写整个应用程序。在内部,将所有函数作为私有变量写入,
varf1=function(){…},varf2=function(){…}等,并公开那些您想要公开的函数。现在可以通过名称、
f1()
f2()
、或
f.call()
等同物对函数进行内部调用,而无需使用
appname.
前缀。这至少会让我对你的一些问题有点过火。谢谢你,我会进一步研究这一点,看看我能想出什么。Epik,我上面的评论并不是对你问题的回答,但它是相关的。模块模式对于组织大型复杂应用程序非常有用,尤其是合作企业应用程序。在很大程度上避免了相互干扰(名称空间冲突)。