首页 > 解决方案 > 确认使用工厂是创建通用多用途点击计数侦听器的最佳(唯一?)方法

问题描述

我创建了以下点击计数工厂,用于将点击计数添加到常规点击事件中已经存在的事件信息中。此函数创建一个 clickCountObj 来跟踪点击次数,以及一个用于捕获给定元素参数上的点击事件并将其与点击计数一起报告回侦听器参数的新函数。

最初,我想把它作为一个类来做,而不是作为一个工厂来做......当我在 Java 中工作时,我会用一个外观类来完成它,所以这就是我的想法。但我已经得出结论,这在 Javascript 中是不可能的,因为您用来创建对象的同一函数将是响应点击而调用的函数,而我看不到解决方法。

这个问题的目的只是为了提高我对 JavaScript 的理解和使用。请让我知道我的上述结论是否错误,或者是否有任何其他替代方法可以更好地做到这一点?

function clickCount(element, listener) {
  let clickCountObj = {};
  clickCountObj.clickCount = 0;
  clickCountObj.clickDelay = 500;
  clickCountObj.element = element;
  clickCountObj.lastClickTime = 0;
  let clickCountListener = function (e) {
//    alert("last click time: " + clickCountObj.clickDelay);
    if ((e.timeStamp - clickCountObj.clickDelay) < clickCountObj.lastClickTime) {
      clickCountObj.clickCount = clickCountObj.clickCount + 1;
//      alert("click count up: " + clickCountObj.clickCount);
    }
    else {
      clickCountObj.clickCount = 1;
    }
    clickCountObj.lastClickTime = e.timeStamp;
    listener.call(element, clickCountObj.clickCount, e);
  };
  if (!element) throw "No element to listener to";
  element.addEventListener("click", clickCountListener);
  return clickCountListener;
}

标签: javascriptclass

解决方案


当然你也可以使用一个类:

 class ClickCounter {
   constructor(element, onClick, delay = 500) {
     this.element = element;
     this.onClick = onClick;
     this.counter = 0;
     this.delay = delay;
     this.lastClicked = 0;

     element.addEventListener("click", () => this.click(), false);
  }

  click() {
    if(Date.now() < this.lastClicked + this.delay)
      return;
    this.lastClicked = Date.now();
    this.onClick.call(this.element, this.counter++);
  }
}

 new ClickCounter(document.body, count => {
   alert(count);
 });

[是] 这样做更好吗?

不,不是。在这里使用类并不是很有用,因为您不想公开属性并且也不需要继承。在这里,工厂似乎是一个好方法。

小旁注:代替

 return clickCountListener;

这样做会更有意义

 return clickCountObj;

因为它会暴露可能有用的设置和计数。


警告:以下内容不严重

回到我在Java工作的时候......

...你接管了那个毫无意义的命名方案(clickCountObj.clickCount)。我想你不会丢失任何必要的信息settings.count...


推荐阅读