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,就可以满足我们的需求了。
分享到:
相关推荐
在决策支持系统中,事件图谱可以提供实时的事件分析,帮助决策者理解事件的前因后果,做出基于客观信息的决策。 百度事件图谱的发展历程显示了从垂直领域知识图谱到通用知识图谱,再到多元异构知识图谱的演进,这...
- 事态调查:承包人需要寻找索赔机会,分析事件前因后果,确保对事件有全面了解。 - 索赔原因:分析事件责任归属,非承包人责任的干扰事件可进行索赔。 - 索赔依据:依据合同判断事件是否符合索赔条件。 - 损失...
2. **违约企业分析**:报告可能对违约的企业进行深入剖析,包括企业的行业背景、财务状况、违约原因以及后续的处理措施,以此揭示企业违约的深层次原因。 3. **信用风险评估**:报告会提供信用风险评估的方法和标准...
1. 如何有效地将事件的前因后果展现出来,使读者能够跟随故事的发展而产生共鸣。 2. 如何在叙事中注入个人的真实感受,使作品富有感染力。 3. 结合本单元课文的写作特点,提升习作的文学价值和艺术表现力。 【教学...
2. 事件还原:详细分析事件的前因后果,包括攻击路径、目标、使用的工具和技巧。 3. 影响评估:确定事件对组织的具体影响,包括数据丢失、系统瘫痪、经济损失等。 4. 教训总结:从事件中提炼出可以改进的地方,如...
【历史解题方法综述】 历史解题方法的掌握对于理解和解答历史...综上所述,解答历史问题需要结合时间、空间、材料含义、所学知识以及答题对象等多个维度,运用历史思维,深入理解事件的前因后果,形成全面的历史认知。
2. 描述事件背景:详实的背景信息有助于读者置身其中,理解事件的前因后果。 五、写好案例的关键 1. 选择复杂情境:复杂的事件能展现多种可能性,激发多元化的思考。 2. 揭示人物心理:揭示教师和学生的心态变化,...
2. 知识点衔接与逻辑性:在教授第二次鸦片战争时,教师注重前后知识点的自然过渡,强调对事件前因后果的深入讲解,通过引导学习、分组讨论和图片史料分析,提升学生分析史料的能力。 3. 太平天国运动:教学中,教师...
3. 《左传》采用编年体,但能全视角记述历史事件,通过多年记述揭示事件的前因后果和历史背景。 4. 司马迁的《史记》“列传”是对《左传》的继承与发展,它以人物为中心,专门记载人物生平,形成传记体裁。 5. ...
2. 《左传》的记述特点:《左传》采用编年之体,虽然将事件分解在不同年份,但它对事件的记述是全视角的,不仅记录了具体事件,还包含了政治、经济、文化、外交、军事等多方面的内容,为读者提供了完整的历史背景。...
2. **事件**:事件部分要求详细记录发生的问题,包括事件的具体日期和时间。准确的时间线对于了解事件的发生顺序和环境至关重要,有助于公正地评估和处理问题。 3. **描述**:这里是事件的详细描述,应包含所有相关...
2. **事件**:这里需要详细描述员工的具体行为或事件,包括事件发生的日期和时间。这确保了事件记录的准确性和时效性,有利于后期分析和决策。 3. **描述**:这一部分是事件的详细叙述,应包含事件的前因后果、涉及...
然而,事故的发生往往是多种因素交织的结果,因此需要从系统的角度出发,全面分析事故的前因后果,采取综合措施以预防事故的发生。 总结来说,煤矿冒顶事故的预防工作应注重人员培训、设备管理和顶板安全管理。通过...
教学设计旨在通过深入理解和朗读,让学生了解武松豪放、倔强、勇敢无畏的性格特征,并能区分事件的前因后果。 教学目标包括三个方面: 1. 学生需要理解课文内容,尤其是武松的人物性格特点,如其豪放不羁和无畏精神...
事件背景,解释事件的前因后果;技术和专业背景,涉及专业知识和技术因素;材料背景,涉及消息来源的可靠性。这些背景信息的分析能为新闻报道提供丰富的内涵和深度。 接下来,我们转向传记的写作背景。传记的核心...
3. 描述事件:对于写作事件,要求学生描绘事件的前因后果,启示应深刻且具体,有助于读者理解。 4. 解读名言:写关于名言的启示时,需要通过情境铺垫来展示这句话对个人的影响。 5. 分析漫画:观察漫画的细节,...
5. 教学目标包括理解课文内容、分析事件前因后果、重点朗读描写武松打虎的部分,并了解武松的性格特点。 6. 教学流程包括初读课文、检查自学情况、分段概括段意、作业安排以及深入学习各段内容,强调对人物性格的...
虽然历史知识点可能较为繁杂,但一旦理清各个事件的前因后果,形成清晰的时间线,就能更好地理解和记忆。历史学习需要尊重史实,答题时需基于史实进行分析,强调历史发展的眼光。课外阅读历史书籍对于深入理解历史...