all files / src/ events.js

100% Statements 32/32
100% Branches 14/14
100% Functions 13/13
100% Lines 31/31
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111                          12× 25× 16× 16×   25×   12×                 12× 12× 10×     10× 10×                                                             16× 16× 18×                       25× 25× 25×                     28×        
/**
 * 事件处理.
 * 将事件保存到 DOM 的某个唯一属性下.
 * 监听则将方法传入到 DOM 下, 方便移除的时候直接从这里取到函数引用.
 */
 
/**
 * 绑定事件
 * @param {string} eventName 事件名
 * @param {function} cb 回调
 * @return {$} 自身实例 实现链式调用
 */
export function on (eventName, cb) {
  this.map(elem => {
    elem[`on${eventName}`] = event => {
      eventHandler(elem, eventName, this.uuid, event)
      event.stopPropagation()
    }
    addEventFn(elem, eventName, this.uuid, cb)
  })
  return this
}
/**
 * 按照参数 来取消回调
 * @param {string} eventName 事件名
 * @param {function} cb 回调
 * @return {$} 自身实例 实现链式调用
 */
export function off (eventName, cb) {
  const isOffAll = arguments.length === 1
  const uuid = this.uuid
  this.map(elem => {
    const events = getEvents(elem, eventName, uuid)
    if (events) {
      if (isOffAll) {
        while(events.length > 1) {
          events.pop()
        }
      }
      const index = events.indexOf(cb)
      events.splice(index, 1)
    }
  })
  return this
}
 
/**
 * 绑定事件, 仅触发一次
 * @param {string} eventName 事件名
 * @param {function} cb 回调
 * @return {$} 自身实例 实现链式调用
 */
export function once (eventName, cb) {
  const uuid = this.uuid
  const context = this
  function newCb (event) {
    cb.call(this, event)
    context.off(eventName, cb)
  }
  return this.on(eventName, newCb)
}
 
/**
 * 触发事件
 * @param {string} eventName 事件名
 * @return {$} 自身实例 实现链式调用
 */
export function trigger (eventName) {
  this.map(elem => elem[eventName] && elem[eventName]())
  return this
}
 
/**
 * 事件调用. 调用存到 节点上的事件
 * @param {HTMLElement} elem  节点
 * @param {string} eventName 事件名
 * @param {string} uuid 唯一码
 */
function eventHandler (elem, eventName, uuid, event) {
  const events = getEvents(elem, eventName, uuid)
  events.map(cb => {
    cb.call(elem, event)
  })
}
 
/**
 * 给节点快速添加方法
 * @param {HTMLElement} elem 节点
 * @param {string} eventName 事件名
 * @param {string} uuid 唯一码
 * @param {function} cb 回调
 */
function addEventFn (elem, eventName, uuid, cb) {
  !elem[uuid] && (elem[uuid] = {Event: {}})
  !elem[uuid].Event[eventName] && (elem[uuid].Event[eventName] = [])
  elem[uuid].Event[eventName].push(cb)
}
 
/**
 * 快速返回当前节点的某个事件
 * @param {HTMLElement} elem 节点
 * @param {string} eventName 事件名
 * @param {string} uuid 唯一码
 * @return {array}
 */
function getEvents (elem, eventName, uuid) {
  return elem &&
    elem[uuid] &&
    elem[uuid].Event &&
    elem[uuid].Event[eventName]
}