事件系统

by 苹果熊

HTML

<div id="app">点我</div>
<div id="loading">加载中..</div>

CSS

#loading {
  display: none
}

JavaScript

;(function() {
	var cache = {},
  		uid = 1,
      expando = '_data' + Date.now()
  
  //获取或新增数据
  this.getData = function(elem) {
  	var guid = elem[expando]
    if(!guid) {
    	guid = elem[expando] = uid++
      cache[guid] = {}
    }
    return cache[guid]
  }
  
  //删除数据
  this.removeData = function(elem) {
  	var guid = elem[expando]
    if(!guid) {
    	return
    }
    delete cache[guid]
    try {
    	delete elem[expando]
    } catch(e) {
    	if(elem.removeAttribute) {
      	elem.removeAttribute('expando')
      }
    }
  }
  
  console.log(cache)
})()

;(function() {
	var nextGuid = 1
  
  //dom对象绑定事件
  HTMLElement.prototype.on = function(type, fn) {
  	var self = this
    var data = getData(this)
    
    if(!data.handlers) {
    	data.handlers = {}
    }
    if(!data.handlers[type]) {
    	data.handlers[type] = []
    }
    if(!fn.guid) {
    	fn.guid = nextGuid++
    }
    data.handlers[type].push(fn)
    
    if(!data.dispatcher) {
    	data.disabled = false
      data.dispatcher = function(event) {
      	if(data.disabled) {
        	return
        }
        if(!data.handlers || !data.handlers[event.type]) {
        	return
        }
        var handlers = data.handlers[event.type]
        if(handlers) {
        	for(var i = 0; i < handlers.length; i++) {
          	handlers[i].call(self, event)
          }
        }
      }
    }
    
    if(data.handlers[type].length == 1) {
    	self.addEventListener(type, data.dispatcher, !1)
    } 
  }
  
  //解绑事件
  HTMLElement.prototype.off = function(type, fn) {
  	var self = this
    var data = getData(self)
    
    if(!data.handlers) {
    	return
    }
    var removeType = function(type) {
    	data.handlers[type] = []
      tidyUp(self, type)
    }
    if(!type) {
    	for(var i in data.handlers) {
      	removeType(i)
      }
      return
    }
    var handlers = data.handlers[type]
    if(!handlers) {
    	return
    }
    if(!fn) {
    	removeType(type)
      return
    }
    if(fn.guid) {
   ...