使用模块显示模式的注册问题

时间:2018-02-25 12:54:23

标签: javascript revealing-module-pattern

我正在建立一个简单的VanillaJS库来切换事物来学习揭示模块模式。

我必须注册像toggler('.tab').setToggleAction(onToggle).init();这样的切换操作。

当我注册时: toggler('.tab').setToggleAction(onToggle).init(); toggler('.accordion-title').setToggleAction(onToggleAccordion).init();

它使用onToggle切换操作替换了toggler('.tab')的{​​{1}}回调函数。

然后我必须做一些调整才能保留每个转换器注册的变量范围。

我认为这有什么问题,这么多函数返回函数。对这种情况有更好的方法吗?



onToggleAccordion

var toggler = function(selector) {
  return (function() {
    var toggles = document.querySelectorAll(selector);

    var _toggleContent = function(toggleFunction) {
      return function() {
        if (toggleFunction) {
          return (toggleFunction.bind(this))();
        }

        throw 'You must set a callback for toggler [' + selector + ']';
      }
    };

    return {
      init: function() {
        for (var x = 0; x < toggles.length; x++) {
          toggles[x].addEventListener('click', _toggleContent(toggleFunction));
        }

        return this;
      },
      setToggleAction: function(callback) {
        toggleFunction = callback;
        return this;
      }
    };
  })();
};

var onToggle = function() {
  alert('You toggled ' + this.id)
  this.parentElement.querySelector('.element-to-be-toggled').classList.toggle('expanded');
};

toggler('.tab').setToggleAction(onToggle).init();
&#13;
.tab {
  background-color: blue;
  display: inline-block;
  padding: 1rem;
  color: #fff;
  box-shadow: 0 0 6px rgba(0, 0, 0, .5);
  list-style: none;
}

.element-to-be-toggled {
  background-color: red;
  display: none;
  color: #fff;
  font-size: 1.3rem;
}

.element-to-be-toggled.expanded {
  display: block;
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

你太复杂了。你不需要IIFE等,只需这样做:

 function toggler(selector){
   const el = document.querySelector(selector);
   let handler = () => { throw "Please add a handler!";};

   return {
     setToggleAction(h){ 
        handler = h; 
        return this;
     },
     init(){
       el.addEventListener("click", (e) => handler(e));
       return this;
     }
  };
}

但在这种情况下,我个人更喜欢OOP而不是关闭:

 class Toggler {
   constructor(selector){
    this.handler =  () => { throw "Set the handler!"; };
    this.el = document.querySelector(selector);
  }

  init(){
    this.el.addEventListener("click", (e) => this.handler(e));
    return this;
  }

  setToggleAction(handler){
    this.handler = handler;
    return this;
  }
}