基于单例模式
设计模式是一种设计思想:用来有效管理代码的思想。经典设计模式:发布订阅
<style>
#box{
position:relative;
left:0;
top:0;
width:100px;
height:100px;
background-color: hotpink;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
//subscribe->sub
let sub=(function (){
let pond={};
const on=function(type,func){
//验证当前事件池中是否存在这个自定义事件:不存在则新增一个
!pond.hasOwnProperty(type)?pond[type]=[]:null;
let arr=pond[type];
//重复验证 或者使用 if(arr.includes(func)) return;
for(let i=0;i<arr.length;i++){
let item=arr[i];
if(item===func){
return;
}
}
arr.push(func);
};
const off=function(type,func){
let arr=pond[type] || [];
for(let i=0;i<arr.length;i++){
if(arr[i]===func){
//想要移除 arr.splice(i,1);
//防止数组塌陷,实现当前项的假删除
arr[i]=null;
break;
}
}
//或者是 arr.filter(item => item!==func);
};
const fire=function(type,...params){
let arr=pond[type]||[];
for(let i=0;i<arr.length;i++){
let item=arr[i];
if(typeof item==="function"){
item(...params);
continue;
}
//如果当前项是null把他删除
arr.splice(i,1);
i--;
}
//或者是 arr.forEach(item=>item(...params));
};
//暴露API
return{
on,
off,
fire
}
})();
let box=document.querySelector('#box');
box.onclick=function(ev){
sub.fire('@A',10,20,ev);
}
function fn1(x,y,ev){
console.log(1,x,y,ev);
}
sub.on('@A',fn1);
function fn2(){
console.log(2);
sub.off('@A',fn1);
sub.off('@A',fn2);
}
sub.on('@A',fn2);
function fn3(){
console.log(3);
}
sub.on('@A',fn3);
function fn4(){
console.log(4);
}
sub.on('@A',fn4);
function fn5(){
console.log(5);
}
sub.on('@A',fn5);
</script>
</body>