我正在构建一个简单的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/