JavaScript中的Event事件对象详解

JavaScript事件【event】


在JavaScript中对于事件来讲,首先,我们需要了解这样几个概念:事件、事件类型、事件绑定、事件监听、事件处理程序(事件侦听器)、事件对象(事件源)、事件流、事件冒泡、事件捕获、事件性能优化(事件委托[事件代理]、移除事件处理程序)、浏览器内核(常见的浏览器兼容问题)等。

 

什么是事件(event):

注:其实事件一直都是存在的(不管有没有绑定 或 监听),它只是没有事件处理程序而已!!!

    JavaScript事件是:浏览器、文档(document)窗口中的发生的特定的交互瞬间;而JavaScript和HTML之间的交互行为就是通过事件来触发的。

事件处理程序:
    事件处理程序:我们用户在页面中进行的点击这个动作,鼠标移动的动作,网页页面加载完成的动作等,都可以称之为事件名称,
即:click、mousemove、load等都是事件的名称。响应某个事件的函数则称为事件处理程序,或者叫做事件侦听器。


 

事件类型: 


在JavaScript中事件大至分为了三大类,分别是一般事件、表单事件、页面事件这3种。
 

  1. UI事件:如load、unload、error、resize、scroll、select、DOMActive,是用户与页面上的元素交互时触发的。
  2. 焦点事件:如blur、DOMFocusIn、DOMFocusOut、focus、focusin、focusout,在元素获得或失去焦点的时候触发,这些事件当中,最为重要的是blur和focus,有一点需要引起注意,这一类事件不会发生冒泡!
  3. 鼠标与滚轮事件:如click、dblclick、mousedown、mouseenter、mouseleave、mousemove、mouseout、mouseover、mouseup,是当用户通过鼠标在页面执行操作时所触发的。
  4. 滚轮事件:mousewheel(IE6+均支持)、DOMMouseScroll(FF支持的,与mousewheel效果一样)。是使用鼠标滚轮时触发的。
  5. 文本事件:textInput,在文档中输入文本触发。
  6. 键盘事件:keydown、keyup、keypress,当用户通过键盘在页面中执行操作时触发。
  7. 合成事件:DOM3级新增,用于处理IME的输入序列。所谓IME,指的是输入法编辑器,可以让用户输入在物理键盘上找不到的字符。compositionstart、compositionupdate、compositionend三种事件。
  8. 变动事件:DOMsubtreeModified、DOMNodeInserted、DOMNodeRemoved、DOMAttrModified、DOMCharacterDataModified等,当底层DOM结构发生变化时触发。IE8-不支持。
  9. 变动名称事件:指的是当元素或者属性名变动时触发,当前已经弃用!
        对于事件的基本类型,随着HTML5的出现和发展,又新增了HTML5事件、设备事件(单点触控)、触摸事件touch、手势事件等各种事件等

其他事件如下:

 

资源事件

事件名称何时触发
error资源加载失败时。
abort正在加载资源已经被中止时。
load资源及其相关资源已完成加载。
beforeunloadwindow,document 及其资源即将被卸载。
unload文档或一个依赖资源正在被卸载。

                                                                   

网络事件

事件名称何时触发
online浏览器已获得网络访问。
offline浏览器已失去网络访问。

 

WebSocket 事件

事件名称何时触发
openWebSocket 连接已建立。
message通过 WebSocket 接收到一条消息。
errorWebSocket 连接异常被关闭(比如有些数据无法发送)。
closeWebSocket 连接已关闭。

 

CSS 动画事件

事件名称何时触发
animationstart某个 CSS 动画开始时触发。
animationend某个 CSS 动画完成时触发。
animationiteration某个 CSS 动画完成后重新开始时触发。

 

CSS 过渡事件

事件名称何时触发
transitionstart

监听过渡事件开始时触发。

transitionrun

监听过渡事件进行时触发。

transitionend

监听过渡事件结束时触发。

 

打印事件

事件名称何时触发
beforeprint打印机已经就绪时触发。
afterprint打印机关闭时触发。

 

剪贴板事件

事件名称何时触发
cut已经剪贴选中的文本内容并且复制到了剪贴板。
copy已经把选中的文本内容复制到了剪贴板。
paste从剪贴板复制的文本内容被粘贴。

 

 

点击这里 - 查看更多JS事件

 

事件流:


浏览器层次顺序:document -> html -> body -> div父元素 -> input子元素】,document最上层祖先元素, input最下层后代元素。

    什么是事件流:事件流是描述从页面中接收事件的顺序【从内到外(冒泡),从外到内(捕获)】;
IE与原来的NetScape(网景),对于事件流提出的是完全不同的顺序。IE团队提出的是事件冒泡流;NetScape的事件流是事件捕获流。
    简单的讲:当给一个DIV绑定一个点击事件,又在DIV里面放一个按扭并给按扭也绑定一个点击事件,此时你点击里面按扭的同时,外面DIV的点击事件也会被触发。

【事件冒泡】、JS阻止事件冒泡方法:event.stopPropagation(),JS阻止默认行为方法:event.preventDefault() 注:这两个方法属于event的。
    所谓事件冒泡 就是事件最开始从最具体的元素(文档中嵌套层次最深的那个点【当前绑定事件的那个元素】)接收,然后逐级向上传播至最不具体的那个节点(document节点,即最上层的节点)。

【事件捕获】、和事件冒泡刚好【相反】,它是事件从最不具体的节点(document)先接收到事件,然后再向下逐一捕获至(文档中嵌套层次最深的那个点【当前绑定事件的那个元素】)。
    简单地说,事件冒泡和事件捕获都是一种事件传递的机制。这种机制可以使事件在不同级
的元素间传递。事件冒泡是从事件触发的源节点,向父节点传递,直到到达最顶节点。而事件
捕获则是从最顶节点,逐步向下传递,直到到达事件触发的源节点。

    在一些标准的浏览器中,如IE9以上,Chrome 、Firefox 、Safari浏览器等,支持这两种冒泡方式。而事实上,
准确的说,是这两种方式的混合方式。因为W3C采取的就是这两种方式的结合:先从顶级节点
开始,将事件向下传递至源节点,再从源节点冒泡至顶节点。

    而在IE及Opera(以下说的都是老版本的欧朋,新版本的欧朋经检测是支持事件捕获的)
下,是不支持事件捕获的。而这个特点最明显体现在事件绑定函数上。IE、Opera的事件
绑定函数是attachEvent,而Chrome等浏览器则是addEventListener,

    而后者比前者的参数多了一个——这个参数是一个布尔值,这个布尔值由用户决定,用户若设为true,
则该绑定事件以事件捕获的形式参与,若为false则以事件冒泡的形势参与。
而这个参数在IE和Opera浏览器中是不存在的——根本原因是它们不支持事件捕获。

 

 事件对象:


   在触发DOM上的某个事件的时候,会产生一个事件对象event,而在这个对象当中会包含着所有与事件有关的信息。
事件对象其中有两个信息,我们最为常用,分别是type和target:
type表示的是被触发事件的类型;
target表示的是事件的目标。

其他:
bubbles:表示事件是否冒泡
cancelable:表示是否可以取消事件的默认行为
currentTarget:表示事件处理程序当前正在处理事件的那个元素
defaultPrevented:表示是否调用了preventDefault()
detail:表示的是与事件相关的细节信息
eventPhase:调用事件处理处理程序的阶段:1表示捕获阶段、2表示处于目标、3表示冒泡阶段


浏览器内核:
1、Trident:(IE内核) Trident内核的常见浏览器有:
IE6、IE7、IE8(Trident 4.0)、IE9(Trident 5.0)、IE10(Trident 6.0);
360安全浏览器(1.0-5.0为Trident,6.0为Trident+Webkit,7.0为Trident+Blink)猎豹极轻浏览器,360极速浏览器(7.5之前为Trident+Webkit,7.5为Trident+Blink)
猎豹安全浏览器(1.0-4.2版本为Trident+Webkit,4.3及以后版本为Trident+Blink)猎豹极轻浏览器,
傲游浏览器(傲游1.x、2.x为IE内核,3.x为IE与Webkit双核)、百度浏览器(早期版本)世界之窗浏览器
最初为IE内核,2013年采用Chrome+IE内核)、2345浏览器、腾讯TT、淘宝浏览器、采编读浏览器、搜狗高速浏览器(1.x为Trident,2.0及以后版本为Trident+Webkit)、阿云浏览器(早期版本)、
瑞星安全浏览器、Slim Browser、 GreenBrowser、爱帆浏览器(12 之前版本)、115浏览器、155浏览器、闪游浏览器、N氧化碳浏览器、糖果浏览器、彩虹浏览器、瑞影浏览器、
勇者无疆浏览器、114浏览器、蚂蚁浏览器、飞腾浏览器、速达浏览器、佐罗浏览器、海豚浏览器(iPhone/iPad/Android)、UC浏览器(Blink内核+Trident内核)等。

2、Gecko:(Firefox内核) Netscape6开始采用的内核,后来的Mozilla FireFox(火狐浏览器) 也采用了该内核,Gecko的特点是代码完全公开。

3、Presto:(Opera前内核) (已废弃) Opera现已改用Google Chrome的Blink内核。

4、Webkit:(Safari内核,Chrome内核原型,开源):它是苹果公司自己的内核,也是苹果的Safari浏览器使用的内核 【是现在大部份移动端:Android安桌,apple苹果采用的内核】。

 

 

JvaScript事件的三种绑定方式【事件处理程序】:


事件绑定方式一【HTML事件处理程序】:就是将事件直接内嵌内HTML结构标签元素内的 【不推荐用,因为不灵活】 

例:

<input type="button" onclick="alert("我是事件绑定方式一:HTML事件处理程序,我是内嵌在HTML结构中的");" value="事件绑定方式一【内嵌】" />


<input type="button" onclick="mupiaoFn()" value="事件绑定方式一【调用】" />



/*------事件绑定方式一:HTML事件处理程序------*/

function mupiaoFn() {
    alert("我是事件绑定方式一:HTML事件处理程序");
};



事件绑定方式二【DOM 0级事件处理程序】:就是把一个函数/方法赋给一个事件处理程的 属性如:id 、class 、元素名等 【用得最多,兼容性好,简单,灵活,跨浏览器 ;缺点:不能绑定多个同类型事件】

例:

<input type="button" name="eventBtn2" id="eventBtn2" value="事件绑定方式二【通用属性绑定】" />



/*------事件绑定方式二:DOM 0级事件处理程序------*/

var Btn2 = document.getElementById("eventBtn2");//给谁绑定事件,就要先获取谁



绑定事件1:【赋给方式】

Btn2.onclick = function() {
    alert("我是事件绑定方式二:DOM 0级事件处理程序");
};


绑定事件2:【调用方式】

function publick() {

    alert("我也是事件绑定方式二:DOM 0级事件处理程序");
};

Btn2.onclick = publick; //注:publick后面不要加()括号,否则会变为立即执行函数!


删除事件:

Btn2.onclick = null; 

注:
    在DOM0级事件处理程序推出之后,被广为使用,可是出现了这样一个问题,当我们希望给同一个元素/标签绑定多个同类型事件的时候(如,为上面的按扭标签绑定2个或是个以上的点击事件),是不被允许的。
    
    那么,此时,出现了另一种事件处理程序,就是DOM2级的事件处理程序,【注:没有DOM1级事件这个概念哦】在DOM2级当中,定义了两个基本方法,
    
    用于处理指定(即绑定)和删除事件处理程序的操作,分别是addEventListener()和removeEventListener(),IE9+、FireFox、Safari、Chrome和Opera都是支持DOM2级事件处理程序的。
    
    对于IE8-,则使用的是IE专有的事件处理程序:两个类似的方法——attachEvent()与detachEvent()。


事件绑定方式三【DOM 2级事件处理程序 / 监听事件】:addEventListener()和removeEventListener()监听事件接收3个参数:事件类型(注:不要加 on), 处理函数 , false:冒泡/true:捕获
    IE中:attachEvent()和detachEvent()监听事件接收2个参数:事件类型(注:要加 on), 处理函数//只支持冒泡

例:

<input type="button" name="eventBtn3" id="eventBtn3" value="事件绑定方式三" />



/*------事件绑定方式三【DOM 2级事件处理程序 / 监听事件】------*/

var Btn3 = document.getElementById("eventBtn3");//给谁绑定事件,就要先获取谁


添加监听事件1:【内嵌方式】

Btn3.addEventListener('click' , function(){

    alert("我是事件绑定方式二:DOM 2级事件处理程序");

} , false); //false:冒泡,true:捕获



添加监听事件2:【调用方式】

Btn3.addEventListener('click' , addevFn , false);

function addevFn() {
    alert("我是事件绑定方式二:DOM 2级事件处理程序 【调用方式】");
};



添加不同的监听事件:鼠标移入事件【调用方式】

Btn3.addEventListener('mouseover' , addevFn2 , false);

function addevFn2() {
    alert(this.value);
};



删除监听事件【注:删除时事件类型名、事件函数名要一一对应哦(就是和添加事件时的参数一样)】

Btn3.removeEventListener("mouseover" , addevFn2, false)



IE8及以下的添加和删除监听事件方法:(注:IE9及以上的就用上面的方法啦)

IE8及以下的添加监听事件1:【内嵌方式】 (注 attachEvent 和 detachEvent方法只传两个参数,前面两个和上面一样,而第3个参数是因为在IE中默认就是冒泡方式,所以不用传第3个参数啦)

Btn3.attachEvent("onclick" , function(){

    alert("我是IE8及以下的添加监听事件方法,【内嵌方式】");
});



IE8及以下的添加监听事件2:【调用方式】(注:attachEvent 和 detachEvent 事件类型前而一定要加  on 才可以哦)

Btn3.attachEvent("onclick" , addevFn3);

function addevFn3() {

    alert("我是IE8及以下的添加监听事件方法,【调用方式】");
};



IE8及以下的删除监听事件

Btn3.detachEvent("onclick" , addevFn3);



事件方面性能优化:事件委托和事件处理程序的移除

    在JavaScript代码当中,添加到页面中的事件越多,页面的性能也就越差。导致这一问题的原因主要有:
每个函数都是对象,都会占用内存。内存中对象越多,性能也就越差。
必须事先指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪时间。
为了进行页面的性能优化,因此我们会采用两种方法,就是上面提到的——事件委托和事件处理程序的移除。

 

事件委托: 


什么时候使用事件委托,其实,简单来说,当时一个页面事件处理程序比较多的时候,我们通常情况下会使用它。

    事件委托主要利用了事件冒泡,只指定一个事件处理程序,就可以管理一个类型的所有事件。例如:我们为整个一个页面制定一个onclick事件处理程序,
此时我们不必为页面中每个可点击的元素单独设置事件处理程序

    事件委托:给元素的父级或者祖级,甚至页面绑定事件,然后利用事件冒泡的基本原理,通过事件目标对象进行检测,然后执行相关操作。其优势在于:

    大大减少了事件处理程序的数量,在页面中设置事件处理程序的时间就更少了(DOM引用减少——也就是上面我们通过id去获取标签,所需要的查找操作以及DOM引用也就更少了)。
    document(注:上面的例子没有绑定在document上,而是绑定到了父级的div上,最为推荐的是绑定在document上)对象可以很快的访问到,而且可以在页面生命周期的任何时点上为它添加事件处理程序,
并不需要等待DOMContentLoaded或者load事件。换句话说,只要可单击的元素在页面中呈现出来了,那么它就立刻具备了相应的功能。
整个页面占用的内存空间会更少,从而提升了整体的性能。

 

移除事件处理程序 

 
    每当将一个事件处理程序指定给一个元素时,在运行中的浏览器代码与支持页面交互的JavaScript代码之间就会建立一个连接。连接数量也直接影响着页面的执行速度。
所以,当内存中存在着过时的“空事件处理程序”的时候,就会造成Web应用程序的内存和性能问题。

那么什么时候会造成“空事件处理程序”的出现呢?

    文档中元素存在事件,通过一些DOM节点操作(removeChild、replaceChild等方法),移除了这个元素,但是DOM节点的事件没有被移除。
innerHTML去替换页面中的某一部分,页面中原来的部分存在事件,没有移除。
页面卸载引起的事件处理程序在内存中的滞留。

 

 

解决方法:
 

  1. 合理利用事件委托;

  2. 在执行相关操作的时候,先移除掉事件,再移除DOM节点;

  3. 在页面卸载之前,先通过onunload事件移除掉所有事件处理程序。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值