Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在对象内管理addEventListener()和removeEventListener()_Javascript_Oop_Event Handling - Fatal编程技术网

Javascript 在对象内管理addEventListener()和removeEventListener()

Javascript 在对象内管理addEventListener()和removeEventListener(),javascript,oop,event-handling,Javascript,Oop,Event Handling,我在javascript中有一个伪类,它有一个方法可以向两个按钮添加和删除侦听器。 代码如下: function FirstObj(secondObj){ this.loginButton = document.getElementById("login"); this.logoutButton = document.getElementById("logout"); this.secondObj = secondObj } FirstObj.prototype = { man

我在javascript中有一个伪类,它有一个方法可以向两个按钮添加和删除侦听器。 代码如下:

function FirstObj(secondObj){
  this.loginButton = document.getElementById("login");
  this.logoutButton = document.getElementById("logout");
  this.secondObj = secondObj
}

FirstObj.prototype = {
  manageListeners : function(state){   //state is a boolean
    var self = this;
    if (state) {
      display += "none";
      this.loginButton.addEventListener("click", function(){
        self.seconfObj.makeSomething();
      }, false);
      this.logoutButton.removeEventListener("click", /*???*/ , false);
    }
    else {
      this.logoutButton.addEventListener("click", function(){
        self.logout();
      }, false);
      this.loginButton.removeEventListener("click", /*???*/ , false);
    }
  }, 
  logout : function(){
    //logout...
  }
}
问题是:如何修改此代码以正确管理事件侦听器?

我认为您无法删除匿名函数的事件侦听器。请改用命名函数:

var myEventListener = function() {
    console.log("Hello World!");
};

myElement.addEventListener("click", myEventListener, false);
myElement.removeEventListener("click", myEventListener, false);
下面是您的类的一个稍加修改的版本,它应该正确管理事件侦听器:

function FirstObj(secondObj){

    var self = this;

    this.loginButton = document.getElementById("login");
    this.logoutButton = document.getElementById("logout");
    this.secondObj = secondObj;

    this.loginButtonClicked = function(){
        self.secondObj.makeSomething();
    };

    this.logoutButtonClicked = function(){
        self.logout();
    };

}

FirstObj.prototype = {

    manageListeners : function(state){

        if (state) {
            display += "none";
            this.loginButton.addEventListener("click", this.loginButtonClicked, false);
            this.logoutButton.removeEventListener("click", this.logoutButtonClicked, false);
        }
        else {
            this.logoutButton.addEventListener("click", this.logoutButtonClicked, false);
            this.loginButton.removeEventListener("click", this.loginButtonClicked, false);
        }

    },

    logout : function(){
        // Log out...
    }

};
但是,如果重写类以利用闭包,可以将其简化为:

function FirstObj(secondObj){

    var self = this;

    var loginButton = document.getElementById("login");
    var logoutButton = document.getElementById("logout");

    var loginButtonClicked = function(){
        secondObj.makeSomething();
    };

    var logoutButtonClicked = function(){
        self.logout();
    };

    this.manageListeners = function(state){

        if (state) {
            display += "none";
            loginButton.addEventListener("click", loginButtonClicked, false);
            logoutButton.removeEventListener("click", logoutButtonClicked, false);
        }
        else {
            logoutButton.addEventListener("click", logoutButtonClicked, false);
            loginButton.removeEventListener("click", loginButtonClicked, false);
        }

    };

    this.logout = function(){
        // Log out...
    };

}

这里我假设
loginButton
logoutButton
secondObj
不需要从类外访问。如果是这样,只需将它们设置为
FirstObj
的属性,并更新引用它们的代码(在范围内使用
this
,在范围外使用
self

是的,我知道这一点,但如果我给它们命名,那么我就有了“this”对象的问题,匿名函数就变成了unnecessary@Kucebe-那可能是,但是您仍然无法删除匿名侦听器,除非您不加选择地取消绑定事件的所有处理程序。命名,不管是什么形式,都是你最好的选择。@Kucebe:我相信无论函数是否匿名,你都有
这个
问题。我总是简单地在正确的范围内声明一个变量
\u this
,并在函数中使用它引用
this
。我不能给这些函数命名,唯一的方法是使用全局变量,但我不想要他们,因为我在做这件事OOP@Steve:问题是事件侦听器调用的函数位于另一个作用域中(logout()函数和secondOBJ.makeSomnething()),因此我需要匿名函数来保存“this”。如果我使用命名函数,作用域的问题将转移到它身上