灏天阁

观察者模式

· Yin灏
/**
 * 创建一个观察者
 */
// 将观察者放在闭包中,当页面加载就立即执行
var Observer = (function () {
  // 防止消息队列暴露而被篡改,故将消息容器作为静态私有变量保存
  var _message = {};
  return {
    // 注册信息接口
    regist: function (type, fn) {
      // 如果此消息不存在则该创建一个该消息类型
      if (typeof _message[type] === "undefined") {
        // 将动作推入到该消息对应的动作执行队伍中
        _message[type] = [fn];
      } else {
        // 如果消息存在
        _message[type].push(fn);
      }
    },
    // 发布信息接口
    fire: function () {
      // 如果该消息没有被注册,则返回
      if (!_message[type]) {
        return;
      }
      // 定义消息信息
      var events = {
          type, // 消息类型
          args: args || {}, // 消息携带数据
        },
        i = 0,
        len = _message[type].length;
      for (; i < len; i++) {
        // 依次执行注册的消息对应的动作序列
        _message[type][i].call(this, events);
      }
    },
    // 移除信息接口
    remove: function (type, fn) {
      // 如果消息动作队列存在
      if (_message[type] instanceof Array) {
        // 从最后一个消息动作遍历
        var i = _message[type].length - 1;
        for (; i >= 0; i--) {
          _message[type][i] === fn && _message[type].splice(i, 1);
        }
      }
    },
  };
})();

/**
 * 拉出来溜溜
 */
// 订阅一条消息
Observer.regist("test", function (e) {
  console.log(e.type, e.args.msg);
});
// 发布这条消息
Observer.fire("test", { msg: "传递参数" }); // test 传递参数

/**
 * 大显身手
 */
// 外观模式 简化获取元素
function $(id) {
  return document.getElementById(id);
}
// 工程师 A
(function () {
  // 追加一则消息
  function addMsgItem(e) {
    var text = e.args.text,
      ul = $("msg"),
      li = document.createElement("li"),
      span = document.createElement("span");
    li.innerHTML = text;
    // 关闭按钮
    span.onclick = function () {
      ul.removeChild(li); // 移除留言
      // 发布删除留言消息
      Observer.fire("removeCommentMessage", {
        num: -1,
      });
    };
    // 添加删除按钮
    li.appendChild(span);
    // 添加留言节点
    ul.appendChild(li);
  }
  // 注册添加评论信息
  Observer.regist("addCommentMessage", addMsgItem);
})();

// 工程师 B
(function () {
  // 更改用户消息数目
  function changeMsgNum(e) {
    // 获取需要增加的用户消息数目
    var num = e.args.num;
    // 增加用户消息数目并写入页面中
    $("msg_num").innerHTML = parseInt($("msg_num").innerHTML) + num;
  }
  // 注册添加评论信息
  Observer.regist("addCommentMessage", changeMsgNum).regist(
    "removeCommentMessage",
    changeMsgNum
  );
})();

// 工程师 C
(function () {
  // 用户点击提交按钮
  $("user_submit").onclick = function () {
    var text = $("user_input");
    if (text.value === "") {
      return;
    }
    // 发布一条评论
    Observer.fire("addCommentMessage", {
      text: text.value,
      num: 1,
    });
    text.value = "";
  };
})();

- Book Lists -