`
bazhuang
  • 浏览: 147441 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

事件的前因后果(2)

阅读更多
2、 认清事件的本质
要想解决这个问题,我们就需要认识一下事件本身。其实onclick本身不是事件,click才是事件,同样onmouseover也不是事件,mouseover才是。
一个页面的html元素设置onclick这些属性的时候,有且只能设置一次,那我们就需要跳出设置onclick这个思维,从click上入手,直接给html元素添加click的事件处理,而且保证都是可以做到独立执行。
这里就需要引入window的一个方法了,不同浏览器的实现不一样,web标准中定义的window.addEventListener,但ie中相应的方法是window.attachEvent。2个方法能处理的事情都是一样的,只是具体的代码实现有点差别。
那我们就看一个具体的示例,怎么给一个html元素添加事件吧。
<script>
  var Event = function(){}
  /**
 * 给元素添加事件
 * @param {Object} dom    htmlElement对象
 * @param {Object} eventName   事件的名称,不包含on
 * @param {Object} callFunc   回调的函数
 * @param {Object} scope   函数操作范围
 * @param {Object} config  参数配置,这个必须为数组形式,eg:[1,"2"]等等
 */
Event.on = function(dom,eventName,callFunc,scope,config){
	//如果已经添加过相同的事件函数,就不处理
	/*var fn = ZERO.EventCache.get(dom,eventName,callFunc.getName());
	if(fn){
		return;
	}*/
	var scope = scope||window;
	var config = config || [];
	var h = function(e){
		var evt = window.event || e;
		callFunc.apply(scope,[evt].concat(config));
	}
	
	//ZERO.EventCache.set(dom,eventName,callFunc.getName(),h);
	
	if(eventName == "mousewheel" && dom.addEventListener){ 
        dom.addEventListener("DOMMouseScroll", h, false);
        Event.on(window, 'unload', function(){
            dom.removeEventListener("DOMMouseScroll", h, false);
        });
    }
	else{
		if(window.attachEvent){
			dom.attachEvent("on"+eventName, h);
		}
		else if(window.addEventListener){
			dom.addEventListener(eventName, h,false);
		}
	}
}

function ck(){
	alert("成功定义了事件了,恭喜");
}

function addEvent(){
	var el = document.getElementById("check");
	Event.on(el,"click",ck);
}
  </script>

  <input id="check" type="button" value="空按钮"/>
  <input type="button" value="给空按钮添加事件" onclick="addEvent();"/>

在点击“给空按钮添加事件”之前点击“空按钮”没有任何响应,点击之后就可以弹出对话框了,说明追加事件成功。如果点了2下“给空按钮添加事件”,这里就会弹出2次对话框,这也说明这个添加事件不会覆盖以前追加的事件,当然也不会影响onclick属性中定义的事件了。

(1) 添加事件分析
这里的添加事件本身Event.on()有5个参数,其中前3个参数是必须的,后面的2个是可配置的。

* @param {Object} dom    htmlElement对象
* @param {Object} eventName   事件的名称,不包含on
* @param {Object} callFunc   回调的函数
其实最终事件触发执行的函数并不是callFunc本身,而是函数中内部定义的h这个函数。然后通过dom. addEventListener或者dom.attachEvent,绑定dom的事件函数。
但这个方法中会有缺陷:
a. 没有判断添加重复事件;
b. 事件添加之后没提供删除功能。
第一个缺陷比较容易理解,重复事件肯定是要防止的,那为什么要提第二个缺陷呢。在什么情况下需要删除事件呢,在事件所依赖的htmlElement从DOM树中移除。

(2) 阻止添加重复事件
针对第一个缺陷,在添加事件的时候我们需要利用cache把事件缓存下来,等到继续添加事件的时候,判断是否已经添加过相同的事件即可。
这个cache需要记录3部分信息,dom对象、事件名称、函数内容及名称。函数名称只需要传入函数对象本身即可,我们可以通过如下方法来简单获取函数名称。
Function.prototype.getName = function(){
	var str = this.toString();
	var className = str.substr(0, str.indexOf('('));
    className = className.replace('function', '');
	if(className.trim()==""){
		return str;
	}
	return className.trim();
}

使用方法比较简单,例子:
  function callback(){
	//function body
  }

  callback.getName();

Event.on这个函数中有如下代码:
var fn = ZERO.EventCache.get(dom,eventName,callFunc.getName());
if(fn){
return;
}
这个就是用来判断是否有重复函数,当然在添加事件之后,需要进行set,
ZERO.EventCache.set(dom,eventName,callFunc.getName(),h);
这句话就是把事件定义保存起来,以便于进行重复、删除等操作的依据。

(3) 删除事件
事件追加之后,也必须要有退出机制才是完整的。要不然一个网页的内存消耗会越来越大,就不是一个好的web程序。
针对window.attatchEvent以及window.addEventListener,相应的也提供了,window.detachEvent及window.removeEventListener。
/**
 * 把对应的事件删除掉
 * @param {Object} dom
 * @param {Object} eventName
 * @param {Object} callFunc
 */
Event.un = function(dom,eventName,callFunc){
	var fn = ZERO.EventCache.get(dom,eventName,callFunc.getName());
	if(fn==null){
		return;
	}
	if (window.removeEventListener) {
		dom.removeEventListener(eventName, fn, false);
    } else if (window.detachEvent) {
		dom.detachEvent("on" + eventName,fn);
    }
	
	//最后需要将事件定义从cache中删除掉
	ZERO.EventCache.remove(dom,eventName,callFunc.getName());
}

这里注意removeEventListener中的第二个参数不是直接传入callFunc呢。其实从Event.on我们就可以看出我们追加事件的时候也不是用callFunc,而是内部创建的函数h,我们已经把这个h放入cache了,删除事件的时候,只要从cache中找到这个h就可以了。

追加事件以及删除事件都用到了cache,给大家看一下这个cache的实现逻辑:
ZERO.EventCache = function(){
	var cache = {};
	return {
		get : function(dom,eventName,name){
			if(cache[dom] && cache[dom][eventName]){
				return cache[dom][eventName][name];
			}
			return null;
		},
		set : function(dom,eventName,name,func){
			if(cache[dom]){
				if(cache[dom][eventName]){
					cache[dom][eventName][name] = func;
				}
				else{
					cache[dom][eventName] = {};
					cache[dom][eventName][name] = func;
				}
			}
			else{
				cache[dom] = {};
				cache[dom][eventName] = {};
				cache[dom][eventName][name] = func;
			}
		},
		remove:function(dom,eventName,name){
			if(cache[dom] && cache[dom][eventName]){
				cache[dom][eventName][name] = null;
			}
		}
	};
}();

可以看到这里定义了3个方法,get、set、remove,就可以满足我们的需求了。
分享到:
评论

相关推荐

    分税制改革的前因后果.docx

    分税制改革的前因后果.docx

    施密特触发器的前因后果.docx

    施密特触发器你懂吗?怎么用运放构成一个简单的施密特触发器?该文档将会为你打开施密特触发器的认知大门

    宏观专题报告:储蓄率下降的前因后果,如何看待我国储蓄率的变化-0307-海通证券-15页.pdf

    宏观专题报告:储蓄率下降的前因后果,如何看待我国储蓄率的变化-0307-海通证券-15页.pdf

    超级兔子让浮动层消失的前因后果

    超级兔子让浮动层消失的前因后果

    EDA/PLD中的商业智能的前因后果

    商业智能(BI)的概念最早是由Gartner Group提出来的。确切地讲,商业智能并不是一项新技术,它是将数据仓库(DW)、联机分析处理(OLAP)、数据挖掘(DM)等技术与客户关系管理(CRM)结合起来应用于商业活动的实际过程当中,...

    论文研究 - 美国银行业智力资本效率的决定因素和后果

    本研究调查了美国银行业智力资本效率的决定因素和后果。 我们发现,银行对不良时期的个人机构记忆会降低其智力资本效率。 我们还发现,智力资本效率限制了银行的冒险行为,并增强了其会计保守性。...

    DB2创建索引和数据库联机备份之间有冲突_一次奇特的锁等待问题案例分析-contracted.doc

    在本文中将具体分析一个 DB2 数据库联机备份期间创建索引被锁等待的实际案例,使读者能够了解这一很有可能经常发生的案例的前因后果,在各自的工作场景能够有效的避免该问题,同时还可以借鉴本文中采用的 DB2 锁等待...

    前沿因果推断文献及相关stata do文件.rar

    因果推断是研究如何更加科学地识别变量间的因果关系及多期DID和事件研究法的数据和代码  客观事物普遍存在着内在的因果联系,人们只有弄清事物发展变化的前因后果,才能全面地、本质地认识事物。基干事物发展的这种...

    调研报告的特点及种类.docx

    这类调查研究报告一般是就某一地域或企业而开展的,通常设计方案到政冶,经济发展,文化艺术,人口数量,自然地理,历史时间等各个领域的基本情况,对调查对象的发展趋势转变,来龙去脉,前因后果来做比较详尽的交待...

    红图新媒体教你如何学习新媒体

    知晓某一热点只是第一步,下一步我们需要了解事情的前因后果,乃至舆论态势。这时候,热点事件分析工具就派上用场了。  1、知微事见  知微事见是一个热点事件分析工具,除了可以自行搜索热点事件外,还提供“事件...

    精通 Verilog HDL:IC 设计核心技术实例详解 part2(total4)

    前7章分别介绍了设计方法概论,Verilog HDL的语法,行为建模,同步设计,异步设计,功能性单元,I2C Slave设计。第8章为微处理器设计,第9章为JPEG Encoder设计。这两章通过两个完整的设计实例,为读者详述了设计...

    mysql关于隐式提交的问题

    整理了一下关于mysql的前因后果,以及如何避免隐式提交

    36页区块链

    区块链概念简述 内容介绍 技术详情 36页看懂区块链的前因后果

    SD卡的一般结构简介

    简单介绍SD卡的前因后果及其一般结构、使用方法、使用环境。

    淘宝技术这十年(阿里巴巴)

    本书从工程师的角度讲述淘宝这个超大规模互联网系统的成长历程,及其所有主动和被动的技术变革的前因后果。书中有幕后故事、产品经验、架构演进、技术启蒙,也有大牛成长、业内八卦、失败案例、励志故事。全书文风...

    淘宝技术这十年 完整版 带批注.pdf

    本书从工程师的角度讲述淘宝这个超大规模互联网系统的成长历程,及其所有主动和被动的技术变革的前因后果。书中有幕后故事、产品经验、架构演进、技术启蒙,也有大牛成长、业内八卦、失败案例、励志故事。全书文风...

    淘宝技术这十年 pdf

    本书从工程师的角度讲述淘宝这个超大规模互联网系统的成长历程,及其所有主动和被动的技术变革的前因后果。书中有幕后故事、产品经验、架构演进、技术启蒙,也有大牛成长、业内八卦、失败案例、励志故事。全书文风...

Global site tag (gtag.js) - Google Analytics