我知道在事件处理函数中将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
。但是在任何一种情况下我仍然无法获取元素。
$.proxy
http://api.jquery.com/jQuery.proxy/,它允许您更改处理程序的上下文。 - charlietfl