`
bazhuang
  • 浏览: 149614 次
  • 性别: 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,就可以满足我们的需求了。
分享到:
评论

相关推荐

    5-8+百度事件图谱技术与应用.pdf

    在决策支持系统中,事件图谱可以提供实时的事件分析,帮助决策者理解事件的前因后果,做出基于客观信息的决策。 百度事件图谱的发展历程显示了从垂直领域知识图谱到通用知识图谱,再到多元异构知识图谱的演进,这...

    施工索赔程序.docx

    - 事态调查:承包人需要寻找索赔机会,分析事件前因后果,确保对事件有全面了解。 - 索赔原因:分析事件责任归属,非承包人责任的干扰事件可进行索赔。 - 索赔依据:依据合同判断事件是否符合索赔条件。 - 损失...

    2020年9月债券市场违约与信用风险事件报告-2020.10-8页精品报告2020.rar

    2. **违约企业分析**:报告可能对违约的企业进行深入剖析,包括企业的行业背景、财务状况、违约原因以及后续的处理措施,以此揭示企业违约的深层次原因。 3. **信用风险评估**:报告会提供信用风险评估的方法和标准...

    新人教统编版五四制四年级上册语文 习作:生活万花筒 教案教学设计.docx

    1. 如何有效地将事件的前因后果展现出来,使读者能够跟随故事的发展而产生共鸣。 2. 如何在叙事中注入个人的真实感受,使作品富有感染力。 3. 结合本单元课文的写作特点,提升习作的文学价值和艺术表现力。 【教学...

    中创安例分析-------------------------------------------------------------

    2. 事件还原:详细分析事件的前因后果,包括攻击路径、目标、使用的工具和技巧。 3. 影响评估:确定事件对组织的具体影响,包括数据丢失、系统瘫痪、经济损失等。 4. 教训总结:从事件中提炼出可以改进的地方,如...

    历史解题方法综述 2.ppt

    【历史解题方法综述】 历史解题方法的掌握对于理解和解答历史...综上所述,解答历史问题需要结合时间、空间、材料含义、所学知识以及答题对象等多个维度,运用历史思维,深入理解事件的前因后果,形成全面的历史认知。

    《如何撰写教学案例》.ppt

    2. 描述事件背景:详实的背景信息有助于读者置身其中,理解事件的前因后果。 五、写好案例的关键 1. 选择复杂情境:复杂的事件能展现多种可能性,激发多元化的思考。 2. 揭示人物心理:揭示教师和学生的心态变化,...

    部编版中国历史-八年级上册-教学反思.docx

    2. 知识点衔接与逻辑性:在教授第二次鸦片战争时,教师注重前后知识点的自然过渡,强调对事件前因后果的深入讲解,通过引导学习、分组讨论和图片史料分析,提升学生分析史料的能力。 3. 太平天国运动:教学中,教师...

    员工处分记录(表格模板、DOC格式).DOC

    2. **事件**:事件部分要求详细记录发生的问题,包括事件的具体日期和时间。准确的时间线对于了解事件的发生顺序和环境至关重要,有助于公正地评估和处理问题。 3. **描述**:这里是事件的详细描述,应包含所有相关...

    员工处分记录(DOC格式).doc

    2. **事件**:这里需要详细描述员工的具体行为或事件,包括事件发生的日期和时间。这确保了事件记录的准确性和时效性,有利于后期分析和决策。 3. **描述**:这一部分是事件的详细叙述,应包含事件的前因后果、涉及...

    煤矿冒顶事故分析页.pdf

    然而,事故的发生往往是多种因素交织的结果,因此需要从系统的角度出发,全面分析事故的前因后果,采取综合措施以预防事故的发生。 总结来说,煤矿冒顶事故的预防工作应注重人员培训、设备管理和顶板安全管理。通过...

    五年级语文下册 第五组 20《景阳冈》教学设计 新人教版-新人教版小学五年级下册语文教案.doc

    教学设计旨在通过深入理解和朗读,让学生了解武松豪放、倔强、勇敢无畏的性格特征,并能区分事件的前因后果。 教学目标包括三个方面: 1. 学生需要理解课文内容,尤其是武松的人物性格特点,如其豪放不羁和无畏精神...

    2020年高考语文一轮复习(核心梳理 固根基)1.2.2.6写作背景的分析与探究 新人教版.doc

    事件背景,解释事件的前因后果;技术和专业背景,涉及专业知识和技术因素;材料背景,涉及消息来源的可靠性。这些背景信息的分析能为新闻报道提供丰富的内涵和深度。 接下来,我们转向传记的写作背景。传记的核心...

    大班案例分析:不情愿的道歉.docx

    再次,教师没有进一步探讨事件的前因后果。例如,从滑梯下面往上爬本身就是不安全的行为,教师应该在此处强调安全规则,防止类似事件再次发生。此外,虽然晓雨受伤,但这并不意味着他没有错误。在处理冲突时,教师...

    英语高考听力四大必读考试重点与十五个常考听力场景.pdf

    3. 事件推断:理解事件的前因后果,挖掘隐藏信息。 四、主题内容 主题型试题要求考生理解对话或独白的主要内容,抓住关键字或主题句提炼主旨。 十五个常考听力场景: 1. 图书馆场景:了解相关术语,如借书卡、图书...

    员工处分记录表.doc

    2. **事件**:详细描述导致处分的具体事件或行为,以便于理解和评估。 3. **日期/时间**:准确记录事件发生的时间,以便于追溯。 4. **描述**:详尽阐述事件的具体情况,包括事件的前因后果和影响。 5. **目击证人**...

    江西省万载中学2020学年高一语文12月月考试题(无答案).doc

    《左传》中对历史事件的记载,虽然也会对某些重要或关键的片段进行倒叙处理,但总体上这种倒叙往往是作为回忆和补充,其目的在于进一步揭示事件的前因后果,而不是单纯为了增加故事的悬念或惊险感。 与之相比,西方...

    应急微直播系统的设计与实现.pdf

    在设计思路方面,应急微直播系统采用了创新的展示方法,利用大图、视频、关系图、时间轴等多种形式,完整且直观地呈现新闻事件的前因后果、背景信息和相关联的事件。这样的设计有助于用户全面了解新闻事件,避免了因...

Global site tag (gtag.js) - Google Analytics