SOURCE

console 命令行工具 X clear

                    
>
console
const Observer = (function() {
  // 防止消息队列暴露而被篡改故将消息容器作为静态私有变量保存
  let _messages = {};
  return {
    // 注册信息接口
    register(type, fn) {
      // 如果此消息不存在则应该创建一个该消息类型
      if (typeof _messages[type] === 'undefined') {
        // 将动作推入到该消息对应的动作执行队列中
        _messages[type] = [fn];
        // 如果此消息存在
      } else {
        // 将动作方法推入该消息对应的动作执行序列中
        _messages[type].push(fn);
      }
    },
    // 发布信息接口
    fire(type, args) {
      // 如果该消息没有被注册,则返回
      if (!_messages[type]) {
        return;
      }
      // 定义消息信息
      const events = {
        type: type,
        // 消息类型
        args: args || {} // 消息携带数据
      };

      // 遍历消息动作
      for (let i = 0, len = _messages[type].length; i < len; i++) {
        // 依次执行注册的消息对应的动作序列
        _messages[type][i].call(this, events);
      }
    },
    // 移除信息接口
    remove(type, fn) {
      // 如果消息动作队列存在
      if (_messages[type] instanceof Array) {
        // 从最后一个消息动作遍历
        for (let i = _messages[type].length - 1; i >= 0; i--) {
          // 如果存在该动作则在消息动作序列中移除相应动作
          _messages[type][i] === fn && _messages[type].splice(i, 1);
        }
      }
    }
  }
})();

// 外观模式  简化获取元素
function $(id) {
  return document.getElementById(id);
}
/*
 * 用户追加评论功能
 */
(function() {
  /**
     * 追加一则消息
     * @param e
     */
  function addMsgItem(e) {
    let 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
      });
    };

    // 添加删除按钮
    ul.appendChild(li);
    // 添加留言节点
    ul.appendChild(li);
  }
  // 注册添加评论信息
  Observer.register('addCommentMessage', addMsgItem);
})();
/*
 * 递增用户信息功能
 */
(function() {
  /**
     * 更改用户消息数目
     * @param e
     */
  function changeMseNum(e) {
    // 获取需要增加的用户消息数目
    let num = e.args.num;
    const $msgNum = $('msgNum');
    // 增加用户消息数目并写入页面中
    $msgNum.innerHTML = parseInt($msgNum.innerHTML) + num;
  }
  // 注册添加评论信息
  Observer.register('addCommentMessage', changeMseNum);
  Observer.register('removeCommentMessage', changeMseNum);
})();
/*
 * 提交信息,触发消息发布功能
 */
(function() {
  // 用户点击提交按钮
  $('useSubmit').onclick = function() {
    // 获取用户输入框中输入的信息
    const text = $('useInput');
    // 如果消息为空则提交失败
    if (!text.value) {
      return;
    }
    // 发布一则评论信息
    Observer.fire('addCommentMessage', {
      text: text.value,
      // 消息评论内容
      num: 1 // 消息评论数目
    });
    text.value = '';
  }
})();
<article>
  <header>
    <span>
      消息数:
    </span>
    <span id="msgNum">
      1
    </span>
  </header>
  <section>
    <h1>
      最新消息发布
    </h1>
    <ul id="msg">
      <li>
        天涯路远
      </li>
    </ul>
  </section>
  <input type="text" id="useInput" />
  <button id="useSubmit">
    提交
  </button>
</article>
article {
   padding: 10px;
   margin: 0 auto;
 }
 
 ul,
 ol,
 li {
   list-style-type: none;
   display: block;
 }
 
 #msg {
   width: 500px;
   margin-left: 0;
   padding-left: 0;
 }
 
 #msg li {
   height: 30px;
   line-height: 30px;
   padding-left: 30px;
   border-radius: 4px;
 }
 
 #msg li:nth-child(odd) {
   background: #DDDDDD;
 }
 
 #msg li:nth-child(even) {
   background: #EEEEEE;
 }
 
 #useInput {
   width: 500px;
   font-size: 16px;
   height: 30px;
   line-height: 30px;
   margin: 20px 0;
   display: block;
   border-radius: 4px;
   -webkit-appearance: none;
   outline: none;
   -webkit-user-select: text;
   user-select: text;
   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
   background-color: transparent;
   border: 1px solid rgba(0, 0, 0, .5);
 }
 
 #useSubmit {
   display: block;
   width: 70px;
   height: 40px;
   border-radius: 4px;
   outline: none;
 }