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;

我看到了其他错误。因为如果 thisundefined 那么 scope 将是 this.handleEvent 但这会引发错误,因为 undefined 不能有 handleEvent 属性.