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

What is the easiest way to pass an element as first argument to event handlers in JavaScript?

本文关键字:程序 事件处理 最简单 方法 是什么 参数传递 JavaScript 元素 第一个      更新时间:2023-09-26

我知道在事件处理函数中将this的值更改为接收事件的元素是非常有用的。但是,我希望我的函数总是在我的应用程序上下文中调用,而不是在元素上下文中调用。这样,我就可以将它们用作事件处理程序和其他方式,例如在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();
        }
    };
}());

第一种方法看起来让我很困惑。是否有一个很好的简单的方法来传递元素接收事件作为第一个参数(最好是一个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));

使用$('body').on('click', overrideContext.bind(app.changeEl));代替,this指向我的app.changeEl函数,我的参数长度为1,只包含p.Event

您可以使用Function.prototype.bind

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

您还可以传入实际的element作为方法

的上下文。
$('body').on('click', overrideContext.bind(app.changeEl));

我认为你的错误是试图控制哪些参数将传递给事件处理程序。如果您真的非常想要这样做,您就必须创建自己的事件处理实用程序,就像jQuery那样,并手动调用处理程序,将您想要的任何内容作为参数传递。

但是,你真的需要吗?如果您依赖与addEventListener相关联的常规处理程序,或者与jQuery中可用的各种方法之一相关联的处理程序,那么您将始终获得event对象作为第一个参数。触发事件的元素将始终在event.target处可用。

考虑到这一点,您可以使用Function.prototype.bind,正如jAndy建议的那样,将this设置为您想要的任何值。