我正在建立一个简单的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;
答案 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;
}
}