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

What's the easiest way i can pass an element as a 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包装的元素)传递给我的事件处理函数,并在应用程序的上下文中调用?假设我使用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));,这指向我的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));

有关更多信息,请参阅Function.call()


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