订阅发布模式概念基础

- 让写出的代码具有可维护性,可复用性,可移植性。不再专注于代码本身,而是站在宏观的角度思考代码,想如何规划和管理代码

- 代码至少满足"低耦合 高内聚"

- 低耦合:每个模块之间的代码没有关联性

- 高内聚:每个模块代码都是由关联性很强的代码组成,都是用来实现单一的功能,得遵守单一职责的原理

- 如何将单独的功能在需要执行的地方执行 ->订阅发布模式

订阅 :做计划

发布 :执行计划

取订阅 :取消计划

function fn1(){}
function fn2(){}
document.addEventListener('click',fn1,false);
document.addEventListener('click',fn2,false);
document.removeEventListener('click',fn2,false);

鼠标点击这件事发生时:

做计划:对事件添加绑定的行为fn1,fn2

取消计划:对事件解除绑定的行为fn2

执行计划:用户点击时

订阅发布模式的基础练习:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="div1"></div>
</body>
</html>
<script>
    //做计划 on
    //取消计划 off
    //执行计划 fire
    let oDiv = document.getElementById('div1');
    function fn1() {
        alert('第一个方法');
    }
    function fn2() {
        alert('第二个方法');
    }
    function fn3() {
        alert('第三个方法');
    }
    on(oDiv,'marry',fn1);
    on(oDiv,'marry',fn2);
    on(oDiv,'marry',fn3);
    off(oDiv,'marry',fn3);
    window.setTimeout(function(){
        fire.call(oDiv,'marry');
    },1000);
    function on(ele,type,fn){
        //有个事件池,放着跟事件相关的行为
        //如何定义跟事件类型相关的事件池(数组)ele['my'+type] +'my'为了和系统事件区分
        if(!ele['my'+type]) {
            ele['my' + type] = [];
        }
        let a = ele['my'+type];
        a.forEach(function (item,index) {   //处理重复绑定
            if(item === fn) return;
        })
        a.push(fn);//把每个行为放在于事件相关的事件池中
    }
    function off(ele,type,fn){
        //1.获取事件池
        let a = ele['my' + type];
        //遍历事件池 是否有这个计划
        if(a && a.length > 0) {
            a.forEach(function (item, index) {
                if (item === fn) {
                    //防止数组发生塌陷,假移除
                    a[index] = null;
                }
            })}
//        for(let i = 0; i < a.length; i++){
//                if(a[i] === fn){
//                    a[i] = null;
//                }
//            }
//        }
    }
    function fire(type){//发布计划 把事件池中的计划取消
        let a = this['my' + type];
        if(a && a.length > 0){
            for(let i = 0; i < a.length; i++){
                if(typeof a[i] === 'function'){
                    a[i].call(this);
                }else{
                    a.splice(i,1);
                    i--;
                }
            }
        }
    }
</script>
原文地址:https://www.cnblogs.com/Lia-633/p/9783483.html