为我的构造函数的所有实例只触发一次eventListener?

时间:2016-03-18 15:01:33

标签: javascript constructor

我的构造函数的所有实例都有一个共享属性:

function Me() { }
Me.prototype.window = {};

我想在window调整大小时更新它的内容,但无论我的构造函数有多少,我都希望每次调整大小事件只执行一次已创建。

逻辑上,如果我将eventListener定义如下,在我的实例的初始化中,它将被多次触发

function Me() {
  window.addEventListener('resize', function() {
    this.window = window.outerWidth;
  }.bind(this));
}
var a = new Me();
var b = new Me();
// on resize, the callback is called twice

我该怎么做?

3 个答案:

答案 0 :(得分:1)

  

我该怎么做?

有一个标志,指示是否绑定事件处理程序。然后,在构造函数中,您只需要检查标志:

if (bindHandler) {
  // ... bind handler
  bindHandler = false;
}

存储标志的方式/位置取决于您。

答案 1 :(得分:-1)

我想回过头来说明我所提供的所有答案,以说明OP未提供所有相关信息。此外,他最终提出的并且标记正确的答案是我提出的并且他击落了。

首先,我提供了可能是最简单的解决方案:

将以下内容完全放在构造函数之外。调整窗口大小时,将更新共享属性 - 对于所有实例。

window.addEventListener('resize', function() {
  Me.prototype.window = window.outerWidth;
};

OP然后添加了新信息,这不会很好,因为如果没有Me的实例,回调仍然会在原型上注册。

然后我提出这个有趣的是,当其他人发布时,他标记为答案。

您的下一个解决方案必须是在注册事件侦听器之前跟踪是否存在Me的任何实例。这意味着您需要跟踪是否存在任何实例:

// Global variabel to track if Me instances exist
var meInstances = false

var me1 = new Me();
meInstances = true;

if(meInstances){
   window.addEventListener('resize', function() {
     Me.prototype.window = window.outerWidth;
   };
}

但是,当我发布它时,响应是:"你完全没有使用所有类,构造函数和类似逻辑的东西。没有隔离,你正在添加大量代码,解决方案并不健全。"事实上,OP随后提出了他自己的解决方案,该解决方案使用数组来存储实例,然后可以检查数组的长度以查看是否存在。我实际上会建议,但是使用布尔标志,因为OP一直说他想要简单。

所以,我提出了这个:

怎么样:

function Me() {
  // This code only runs when instance is being made

  // This instance is registers a callback
  window.addEventListener('resize', function() {

    // Callback modifies single Prototype that all instances share
    Me.prototype.window = window.outerWidth;
  });
}

Me.prototype.window = {};

现在,我并不完全赞同这是一个很好的解决方案,但是在每个建议之后,OP都会加入所有限制,这似乎是最后的选择。但是,又被拒绝了。

答案 2 :(得分:-1)

在这里添加我在最终代码中使用的解决方案。
我已经为完整性添加了destroy方法:

function Me() {
  this.init();
}

Me.prototype.window = 0;

// function used to update this.window
Me.prototype.onResizeBound = null;
Me.prototype.onResize = function() {
  Me.prototype.window = window.outerWidth;
};

// if there are no instances of Me, initialize the event listener
// then, add this instance to the instances list
Me.prototype.init = function() {
  if (this.instances === 0) {
    Me.prototype.onResizeBound = this.onResize.bind(this);
    window.addEventListener('resize', Me.prototype.onResizeBound);
  }
  this.instances++;
};

// remove this instance to the instances list
// if there are no more instances in the list, remove the event listener
Me.prototype.destroy = function() {
  this.instances--;

  if (this.instances === 0) {
    window.removeEventListener('resize', Me.prototype.onResizeBound);
  }
};
Me.prototype.instances = 0;

示例:

var a = new Me(); // added event listener
var b = new Me(); // not added event listener since one is already set
b.destroy(); // not removed event listener since one instance is still there
a.destroy(); // removed event listener since there are not other instances