Javascript/jQuery 使用关键字 this 的对象内部事件处理程序范围
Javascript/jQuery Event Handler Scope inside object using keyword this
几天来我一直在努力解决这个问题。我已经阅读了很多关于 SO 的问题,并用许多不同的方式用谷歌搜索了它,read/attempted 我发现的一切。到目前为止,我没有发现任何对我有用的东西,而且我已经重写了我的代码一百万次,它似乎在尝试不同的方法来做到这一点。
我觉得我在这里遗漏了一些非常明显的东西,也许只需要朝着正确的方向推动。如果我的做法完全错误并且需要重组所有内容,我也可以这样做。
基本上我正在使用的是前端 "controller" 找不到更好的词了,它初始化一些变量,设置一些事件侦听器并响应用户操作。
我不关心我是使用 jQuery 还是纯粹的 JavaScript,我只是希望它能工作,即使我必须重写整个东西。我的目标是重负载下的速度和性能。我正在考虑的另一个选择是 node.js 但我对此经验有限,所以希望用 jQuery.
来解决这个问题
当页面加载时,我没有收到错误,但是当我单击其中一个我设置了事件侦听器的项目时,我收到错误... TypeError: Cannot Read Property 'apply' of undefined.
它指的是以 var scope = this ? function(e)...
开头的相应行
该行的目的是让 this
关键字引用控制器对象,以便我可以从事件处理程序方法中调用对象方法。虽然看起来它可能没有像我预期的那样工作。
我尝试只使用 .on
来设置点击和更改处理程序,但我也遇到了范围问题。再次感谢您的帮助。
(function ($) {
$(function () { //document ready
function Controller(authId, authKey) {
this.user.id = authId;
this.user.key = authKey;
this.init();
};
Controller.prototype = {
eventChange: [ "amt", "multi" ],
eventClick: [ "double", "half", "high", "low" ],
event: { refresh: ['amt', 'multi'], update: ['double', 'half'], process: ['high', 'low'] },
user: { id: '', key: '', name: '', balance: '' },
init: function () {
this.initEvents();
},
initEventz: function() {
for (var i = 0; i < this.eventChange.length; i += 1) {
var ele = document.getElementById(this.eventChange[i]);
var scope = this ? function(e) { this.handleEvent.apply(this, ["change"]); } : this.handleEvent;
if(document.addEventListener) {
ele.addEventListener("change", scope, false);
} else if(document.attachEvent) {
ele.attachEvent("onchange", scope);
}
}
for (var i = 0; i < this.eventClick.length; i += 1) {
var ele = document.getElementById(this.eventClick[i]);
var scope = this ? function(e) { this.handleEvent.apply(this, ["click"]); } : this.handleEvent;
if(document.addEventListener) {
ele.addEventListener("click", scope, false);
} else if(document.attachEvent) {
ele.attachEvent("onclick", scope);
}
}
},
handleEvent: function (e) {
var eventId = e.target.id;
for (var event in this) {
if (this.hasOwnProperty(event)) {
console.log(event);
}
}
}
};
var Controller = new Controller($("#auth").val(), $("#key").val());
}); //end document ready
})(jQuery);
您正在丢失对此的引用。
您可以使用以下代码解决该问题:
var scope = this ? function(e) { this.handleEvent.apply(this, ["click"]); }.bind(this) : this.handleEvent;
但是如果您希望处理程序可以通过引用 this
访问其范围内的元素,您应该这样写:
var scope = this ? function(e) { this.handleEvent.apply(ele, ["click"]); }.bind(this) : this.handleEvent;
或这个
var that = this;
var scope = this ? function(e) { that.handleEvent.apply(ele, ["click"]); } : this.handleEvent;
我看到了其他错误。因为如果 this
是 undefined
那么 scope
将是 this.handleEvent
但这会引发错误,因为 undefined
不能有 handleEvent
属性.
几天来我一直在努力解决这个问题。我已经阅读了很多关于 SO 的问题,并用许多不同的方式用谷歌搜索了它,read/attempted 我发现的一切。到目前为止,我没有发现任何对我有用的东西,而且我已经重写了我的代码一百万次,它似乎在尝试不同的方法来做到这一点。
我觉得我在这里遗漏了一些非常明显的东西,也许只需要朝着正确的方向推动。如果我的做法完全错误并且需要重组所有内容,我也可以这样做。
基本上我正在使用的是前端 "controller" 找不到更好的词了,它初始化一些变量,设置一些事件侦听器并响应用户操作。
我不关心我是使用 jQuery 还是纯粹的 JavaScript,我只是希望它能工作,即使我必须重写整个东西。我的目标是重负载下的速度和性能。我正在考虑的另一个选择是 node.js 但我对此经验有限,所以希望用 jQuery.
来解决这个问题当页面加载时,我没有收到错误,但是当我单击其中一个我设置了事件侦听器的项目时,我收到错误... TypeError: Cannot Read Property 'apply' of undefined.
它指的是以 var scope = this ? function(e)...
该行的目的是让 this
关键字引用控制器对象,以便我可以从事件处理程序方法中调用对象方法。虽然看起来它可能没有像我预期的那样工作。
我尝试只使用 .on
来设置点击和更改处理程序,但我也遇到了范围问题。再次感谢您的帮助。
(function ($) {
$(function () { //document ready
function Controller(authId, authKey) {
this.user.id = authId;
this.user.key = authKey;
this.init();
};
Controller.prototype = {
eventChange: [ "amt", "multi" ],
eventClick: [ "double", "half", "high", "low" ],
event: { refresh: ['amt', 'multi'], update: ['double', 'half'], process: ['high', 'low'] },
user: { id: '', key: '', name: '', balance: '' },
init: function () {
this.initEvents();
},
initEventz: function() {
for (var i = 0; i < this.eventChange.length; i += 1) {
var ele = document.getElementById(this.eventChange[i]);
var scope = this ? function(e) { this.handleEvent.apply(this, ["change"]); } : this.handleEvent;
if(document.addEventListener) {
ele.addEventListener("change", scope, false);
} else if(document.attachEvent) {
ele.attachEvent("onchange", scope);
}
}
for (var i = 0; i < this.eventClick.length; i += 1) {
var ele = document.getElementById(this.eventClick[i]);
var scope = this ? function(e) { this.handleEvent.apply(this, ["click"]); } : this.handleEvent;
if(document.addEventListener) {
ele.addEventListener("click", scope, false);
} else if(document.attachEvent) {
ele.attachEvent("onclick", scope);
}
}
},
handleEvent: function (e) {
var eventId = e.target.id;
for (var event in this) {
if (this.hasOwnProperty(event)) {
console.log(event);
}
}
}
};
var Controller = new Controller($("#auth").val(), $("#key").val());
}); //end document ready
})(jQuery);
您正在丢失对此的引用。
您可以使用以下代码解决该问题:
var scope = this ? function(e) { this.handleEvent.apply(this, ["click"]); }.bind(this) : this.handleEvent;
但是如果您希望处理程序可以通过引用 this
访问其范围内的元素,您应该这样写:
var scope = this ? function(e) { this.handleEvent.apply(ele, ["click"]); }.bind(this) : this.handleEvent;
或这个
var that = this;
var scope = this ? function(e) { that.handleEvent.apply(ele, ["click"]); } : this.handleEvent;
我看到了其他错误。因为如果 this
是 undefined
那么 scope
将是 this.handleEvent
但这会引发错误,因为 undefined
不能有 handleEvent
属性.