JS基础——事件绑定
上一篇博客JS事件对象中,老师问JS事件处理和VB中的事件处理有什么联系?先来解决一下这个问题。举个VB.net中事件处理的样例(JS敲久了,VB习惯的都不熟悉了,看来得常常回想了):
1、事件处理VB VS JS
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MsgBox("helo!")
MsgBox(sender.width) '弹出触发这个事件对象的宽度
MsgBox(sender.name) '弹出触发这个事件对象的名字
MsgBox(TypeOf e Is Object) 'TRUE
MsgBox(TypeOf sender Is Object) 'true
End Sub</span>
解析:看上面的事件处理代码:能够看出来组成和JS中的一模一样,相同包含触发事件的对象button1,事件处理函数Click和对应要运行的函数(这里理解为事件更好)Button1.Click(即要运行的行为),可见仅仅是他们的表示方式有些不一样而已。
那么在这个事件处理中有两个參数sender和e,它们的作用又是干嘛的呢?
1、sender:触发事件的对象,这里指button,在代码中通过弹出sender.name来获取触发该事件对象的名字,sender.width来获取触发该事件对象的宽度等,可见通过sender能够获取触发该事件对象的相关信息。类型为object
2、e:这里看到e有没有认为跟JS中事件绑定中传入的參数e有点儿一样呢?它在VB中就相当于JS中浏览器默认传递给事件处理的一个事件对象。通过e能够获取相应事件的相关信息,相同在上篇博客中通过JS中事件处理中的事件对象来获取一些事件的相关信息在VB中也是能够做到的,比如改动键的样例,在VB中通过e也是能够来进行推断用户按下的键值的,仅仅是语法上不同罢了。相同它的类型为object
综上,JS中的事件处理和VB中的没啥差别(个人大胆的推測中。。。),那么了解了事件对象后,对后面理解事件绑定会有非常大的帮助。
二JS事件绑定
先理解一下事件绑定:事实上,这里说到事件绑定,还是非常熟悉,C#中用到的托付就是这么个思想,VB中也用到了事件绑定AddHandler,removeHandler等都是事件绑定思想的一个应用。核心思想都是讲一个方法或事件挂载到还有一个事件或方法上去运行,调用时就好像一个代理,直接调用同一个事件或方法就能够运行规定好的同一种类型(或理解为遵循同一种规则)的全部方法或事件(纯属个人编造的句子)。
这里同一种规则在JS的事件绑定中能够理解为:比方相同都有一个触发事件的对象,后面紧跟着一个事件处理函数(onClick),在后面就是要运行的方法的详细过程等。
对于传统的事件绑定,JS中常见的有两种形式,内联和脚本样式,这样的通常能够用来处理简单的事件函数,对于略微复杂的,会有非常大弊端:
1、不能同一时候绑定多个函数。
2、统一元素上多个同样的函数,不可以自己主动屏蔽同样的函数
3、函数体内的this指向window,而不是当前的DOM对象
4、函数运行的顺序不能依照绑定顺序运行
5、须要在函数体内进行标准化event对象
针对以上问题,JS中採取现代事件绑定,但W3C中直接採取现代事件绑定addEventListener可解决以上问题,IE中(attachevent)仅仅能解决第一条和第5条。为了解决IE中this传递和标准化event问题,能够採用call传值的方式来解决。
function addEvent(obj,type,fn){
if ( typeof obj.addEventListener!='undefined'){ //W3C
obj.addEventListener(type,fn,false);
}else if(typeof obj.attachEvent!='undefined'){//IE
obj.attachEvent('on'+type,function(){
fn.call(obj,window.event);//利用对象冒充来解决this传递问题,window.event參数的传递用来解决标准化event的问题。
});
}
}
通过以上现代事件绑定后,出现一个问题,因为採用call来进行对象冒充,导致后面封装时,删除不须要的函数时出现困难,主要原因是无法识别究竟是要删除哪一个函数,假设为每个函数加上一个ID,删除时,仅仅要指明要删除的ID就能够了。针对这个问题,我们在基于JS一切皆对象的原理上,能够为每个事件加入一个属性ID,来进行识别。同一时候,针对于上述IE中出现的其余问题,採取了传统事件绑定来模拟现代事件绑定的方式来解决同样函数屏蔽和删除指定函数的问题。
1、模拟现代事件绑定
//为每一个事件分配一个计数器
addEvent.ID=1; //为了防止全局变量的灾难,所以将事件ID变为addEvent的属性 function addEvent(obj,type,fn){
if ( typeof obj.addEventListener!='undefined'){ //W3C
obj.addEventListener(type,fn,false);
}else {
//创建一个存放事件的哈希表
if(!obj.events)obj.events={};
//第一次运行时运行
if(!obj.event[type]){
//创建一个存放事件处理函数的数组
obj.events[type]=[];
//把第一次的事件处理函数先存储到第一个位置
if(obj['on'+type]) obj.events[type][0]=fn;
}else {
//同一个注冊函数进行屏蔽,不加入到计数器中
if(addEvent.equal(obj.events[type],fn)) return false; //假设之后的函数与第一个相等,自己主动屏蔽
}
//从第二次開始,用事件计数器来存储
obj.events[type][addEvent.ID++]=fn;
//运行事件处理函数
obj['on'+type]=addEvent.exec(); //这里讲事件处理运行函数进一步封装
} }
2、封装事件处理的运行函数
addEvent.exec=function(event){ //这里须要通过传递的事件来获取事件类型
var e=event||addEvent.fixEvent(window.event); //通过addEvent事件中传递的event对象来获取type类型
var es=this.events[e.type] //将obj用this来取代获取obj对象
for (var i in es){ //这里要用this.events[e.type],不能直接用obj.events
es[i].call(this,e); //IE须要传递this来弹出this.value值,解决IE中的this传递问题
}
}
3、同一个注冊函数进行屏蔽
addEvent.equal=function(es,fn){
for(var i in es){
if(es[i]==fn) return true;
}
return false;
}
4、删除事件
function removeEvent(obj,type,fn){
if(typeof obj.removeEventListener!='undefined'){
obj.removeEventListener(type,fn,false);
}else {
for (var i in obj.events[type]){
if(obj.events[type][i]==fn){
delete obj.events[type][i];
}
}
}
}
能够看出,IE在模拟现代事件过程中,事件对象e起了非常大作用,通过它能够获取加入事件的类型及ID,而在删除时,正好借助于事件对象获取的属性来进行删除,非常方便。同一时候,理解了跨浏览器事件绑定的封装,对后面JS封装库理解也就简单了非常多,封装时,非常多方法也都是在这个基础上来进行的,最后若想实现连缀,须要返回封装库的一个核心对象,这也是后面学习JQuery的一个核心。
以上纯属个人理解,不代表百度或CSDN的意见,若參考,请认真斟酌!
JS基础——事件绑定的更多相关文章
- js基础——事件绑定(事件监听)
JavaScript事件一共有三种监听方法分别如下: 1.事件监听一夹杂在html标签内 <div id="box" onClick="alert('HELLO W ...
- JS中事件绑定的三种方式
以下是搜集的在JS中事件绑定的三种方式. 1. HTML onclick attribute <button type="button" id="upl ...
- JS的事件绑定、事件流模型
.t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.JS事件 (一)JS事件分类 1.鼠标事件:click/dbclick ...
- JS中事件绑定函数,事件捕获,事件冒泡
1 事件绑定:事件与函数绑定以及怎么取消绑定 1.1 元素.onclick这种形式,如下: <div id="div1">aaa</div> <scr ...
- JS中事件绑定问题
今天编写代码时遇到一个问题,我的判断语句(IFLESE)老是顺序执行结束后又跳到中间的语句里去执行了,找了半天没发现问题,最后才发现是事件绑定闹得鬼,不多说,先上代码为敬. JSP里 <butt ...
- 深入理解JS的事件绑定、事件流模型
一.JS事件 (一)JS事件分类 1.鼠标事件: click/dbclick/mouseover/mouseout 2.HTML事件: onload/onunload/onsubmit/onresi ...
- JS基础——事件操作总结
通用事件绑定 function bindEvent(elem,type,fn) { elem.addEventListener(type,fn); } let a =document.getEle ...
- 4.Knockout.Js(事件绑定)
前言 click绑定在DOM元素上添加事件句柄以便元素被点击的时候执行定义的JavaScript 函数.大部分是用在button,input和连接a上,但是可以在任意元素上使用. 简单示例 <h ...
- js中事件绑定要注意的事项之如何在方法中自己打印自己的值
下面是错误的js方法绑定,这样写会造成在方法中不能用 调用方法的dom本身的一些 东西,如各种属性或者jq对象等. <!DOCTYPE html> <html> <hea ...
随机推荐
- Hadoop0.20.2 Bloom filter应用演示样例
1. 简单介绍 參见<Hadoop in Action>P102 以及 <Hadoop实战(第2版)>(陆嘉恒)P69 2. 案例 网上大部分的说明不过依照<Hadoop ...
- Android 源代码结构(转)
简介 在使用Andriod SDK进行应用程序开发的时候,我们需要对源代码进行调试,有可能需要进入到某个Android API函数内部进行跟踪调试.但是,如果目标版本的SDK没有关联对应版本的源代码的 ...
- URAL 1141. RSA Attack RSA加密演算法
标题来源:URAL 1141. RSA Attack 意甲冠军:给你e n c 并有m^e = c(mod n) 求 m 思路:首先学习RSA算法 here 过程大致是 1.发送的信息是m 2.随机选 ...
- HTTP Cookie深入理解
HTTP Cookie 概述:Cookie通常也叫做网站cookie,浏览器cookie或者http cookie,是保存在用户浏览器端的,并在发出http请求时会默认携带的一段文本片段.它可以用来做 ...
- 十天学Linux内核之第四天---如何处理输入输出操作
原文:十天学Linux内核之第四天---如何处理输入输出操作 真的是悲喜交加呀,本来这个寒假早上8点都去练车,两个小时之后再来实验室陪伴Linux内核,但是今天教练说没名额考试了,好纠结,不过想想就可 ...
- SQL Server中的CLR编程——用.NET为SQL Server编写存储过程和函数
原文:SQL Server中的CLR编程--用.NET为SQL Server编写存储过程和函数 很早就知道可以用.NET为SQL Server2005及以上版本编写存储过程.触发器和存储过程的,不过之 ...
- 计数排序(C语言版本)
让我们来谈谈数的排序思维: 计数排序假定待排序的全部元素都是介于0到K之间的整数.计数排序使用一个额外的数组countArray.当中第i个元素是待排序数组array中值等于i的元素的个数.然后依据数 ...
- DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能
DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能 一.引言 在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作.此时客户会在自己 ...
- mac_Alfred_快捷设置
1.安装(不说了去 Google 吧) 2.基础快捷键:option+space 3.打开应用程序:Alfred 几乎是一切程序的入口,你再也不需要找妈妈要开始菜单了.用快捷键呼出Alfred,输入任 ...
- C#-TextBox-登录表单password无形---ShinePans
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...