我正在构建一个简单的VanillaJS库,该库可以切换内容以了解显示模块模式。

我必须注册类似toggler('.tab').setToggleAction(onToggle).init();的切换动作。

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

它用onToggle切换动作替换了toggler('.tab')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();

.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;
}

<ul>
  <li>
    <h3 id="tab1" class="tab">Tab1 (click here)</h3>
    <div class="weird-content">
      <ul>
        <li>
          Blah blah
        </li>
        <li>
          <div class="element-to-be-toggled">
            Toggler ipsum dolor sit amet, consectetur adipisicing elit. Eos, adipisci velit vitae, distinctio ipsum non! Facere iure, rerum non. Quibusdam.
          </div>
        </li>
      </ul>
    </div>
  </li>
  <li>
    <h3 id="tab2" class="tab">Tab2 (click here)</h3>
    <div class="weird-content34234">
      <ul>
        <li>
          Lorem ipsum dolor sit.
          <div class="element-to-be-toggled">
            Toggler ipsum dolor sit amet, consectetur adipisicing elit. Eos, adipisci velit vitae, distinctio ipsum non! Facere iure, rerum non. Quibusdam.
          </div>
        </li>
        <li>
          Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quam, eligendi.
        </li>
      </ul>
    </div>
  </li>
  <li>
    <h3 id="tab3" class="tab">Tab3 (click here)</h3>
    <div class="element-to-be-toggled">
      Toggler ipsum dolor sit amet, consectetur adipisicing elit. Eos, adipisci velit vitae, distinctio ipsum non! Facere iure, rerum non. Quibusdam.
    </div>
  </li>

</ul>

最佳答案

您使事情变得过于复杂。您不需要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;
  }
}

关于javascript - 使用模块显示模式的注册问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48973653/

10-15 05:37