JavaScript 事件类型、绑定方式、事件流、处理程序分析

目录

什么是事件?

事件类型

传统事件类型

表单事件

window事件

鼠标事件

Dom事件

Html5事件

触摸屏和移动设备事件

事件绑定的几种方式:

 JS事件流理解

DOM事件流

事件处理程序


什么是事件?

JavaScript 创建动态页面。事件是可bai以被du JavaScript 侦测到的行为。 网页中的每个元素都可zhi以产生某些可以触发 JavaScript 函数或程序的事dao件。

比如说,当用户单击按钮或者提交表单数据时,就发生一个鼠标单击(onclick)事件,需要浏览器做出处理,返回给用户一个结果。

主要事件表:

事件类型

事件类型是用来说明发生什么类型事件的字符串,如:click、dblclick、keydown、mouseover、mouseout等等,其分为如下几种情况:

传统事件类型

处理鼠标、键盘、html表单和window对象的事件是web应用中常用的得到广泛支持。

表单事件

说白话一点,简练一点后,即:表单事件,如提交表单和重置表单时,<form>元素分别触发submit事件和reset事件,以及用户与表单类按钮元素交互时,会触发click事件。另外还有当用户通过输入文字,选择选项或选择复选框来改变表单元素状态时,此时会触发change事件。当选中或着移出表单元素(如:text、password、textarea等)会分别触发focus和blur事件。tips:focus和blur事件不会冒泡,但其他所有表单事件都阔以。

window事件

官方术语☞:window事件是指事件的发生与浏览器窗口本身而非窗口中显示的任何特定文档内容相关。
1:load事件,是指外部资源完全加载完毕,浏览器才触发事件处理函数。
2:DOMContentLoaded及readystatechange事件是load事件的替代方案,即当文档和其元素为操作准备就绪,但外部资源未完全加载,浏览器也会尽早地触发它们。
3:unload事件:当用户离开当前文档转向其他文档时,触发该事件,但有一点蛮好的,就是unload事件阔以保存用户的状态。
4:beforeunload事件:与unload事件类似,但有一点特色,就是当它转向其它文档时,提供了询问用户是否确定离开当前页面的机会。
5:window对象中的onerror属性有点像事件处理程序(但不是),当js出差错时触发它。
6:resize事件和scroll事件:当用户调整浏览器窗口大小或滚动它是触发。
window当然还有一些其它一些事件如:focus及blur

鼠标事件

当用户在文档上移动或单击鼠标时都会产生鼠标事件。
其中:
1:clientX和clientY属性指定了鼠标在窗口坐标中的位置。
2:button和which属性指定了按下的鼠标键是哪个。
3:对于click事件,detail属性指定了其是单击,双击(dblclick),三击。
4:鼠标移动时,就会触动mousemove事件,因此mouseover事件处理程序一定不能触发计算密集型任务。
5:当注册mousedown和mousemove事件处理程序,阔以探测和响应鼠标的拖动。
6:在mousedown事件和mouseup事件队列之后,浏览器也会触发click事件。
7:当单击鼠标右键时,浏览器通常会显示上下文菜单(context menu),在显示之前,它们会通常会触发contextmenu事件。
8:当用户滚动滑轮时,浏览器触发mousewheel事件(注意:firefox中是DOMMouseScroll事件)。传递的事件对象属性是指滚轮转动的大小和方向。

Dom事件

dom事件蛮多的,就举例如下:
1:3级dom事件规范标准化了不冒泡的focusin和focusout事件来取代冒泡的focus和blur事件。
2:标准化来不冒泡的mouseenter和mouseleave事件来取代冒泡的mouseover和mouseout事件。

Html5事件

html5及相关标准定义了大量新的web应用API。
如:
1:广泛推广的html5特性之一是加入用于播放音频和视频的<audio>和<video>标签,其中有关于网络事件、数据缓冲状况和播放状态的事件状态。
2:html5的拖放API,有着7个事件类型,分别是:drag、drop、dragend、dragstar、dragover、dragenter、dragleave。
3:html5定义了历史管理机制,它允许web应用同浏览器的返回和前进按钮交互。这个机制就涉及的事件是hashchange和popstate事件。
4:html5为html表单也定义了大量的新特性。如表单验证机制,其中当验证失败时在表单元素上会触发invaild事件。
5:html5包含了对离线web应用的支持,其中俩个最重要事件是offline事件和online事件,无论何时浏览器失去或得到网络连接都会在window对象上触发它们。
6:也有很多web应用api都使用message事件进行异步通信。

触摸屏和移动设备事件

强大的移动设备的广泛采用(特别是使用触摸屏的那些设备)需要建立新的事件类别。
1:当旋转这些设备时会触发orientationchange事件。
2:手势事件:当手势事件开始时会触发gesturestart事件,而手势结束时生成gestureend事件。在俩者事件之间就是跟踪手势过程的gesturechange事件队列,其中这些事件传递的事件对象有数字属性scale和rotation。
3:触摸事件:触摸屏幕则触发touchstart事件,而当手指移动时会触发touchmove事件,当手指离开屏幕会触发touchend事件。

事件绑定的几种方式:

事件处理程序即给元素绑定事件的方式有下列几种:HTML事件处理程序、DOM0级事件处理程序、DOM2级事件处理程序、IE事件处理程序、跨浏览器事件处理程序。其实这些方式就是一个逐步优化和实现跨浏览器的过程。

1、HTML事件处理程序:直接在html的标签中添加事件属性,例如:

<div οnclick="fun()"></div>

这样做很是不好,有下列两大缺点,这也是如今在开发中很难见到这样绑定事件的原因。

(1)存在一个时差问题,因为用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件(比如js代码还没有下载下来),由此会引发错误。

(2)HTML与js代码紧密耦合。如果要更换事件处理程序,就要改动两个地方:HTML代码和JS代码,这非常不利于后期代码的维护。

所以这种方法在开发中基本不用,但是还是得了解它是怎么个用法和为什么不用它的原因。

2、DOM1级事件处理程序:将一个函数赋值给一个事件处理程序属性,表示元素的方法,这时的事件处理程序是在元素的作用域中运行。例如:

var oBox = document.getElementById("container");

oBox.onclick = function() {}

这种做法的优点是:简单和所有浏览器都支持。

缺点是:只能给该元素绑定一个事件。于是出现DOM2级事件处理程序。

3、DOM2级事件处理程序:addEventListener()添加事件,removeEventListener()删除事件。可添加多个,执行顺序与添加顺序相同。两个方法都接受三个参数:

第一个参数:事件名称

第一个参数:作为事件处理程序的函数

第一个参数:捕获值false(不捕获)/true(捕获),不写表示默认值false

例如:

var oBox = document.getElementById("container");

oBox.addEventListener("click",fn(),false);

oBox.removeEventListener("click",fn(),false);

function fn(){//执行代码}

关于第三个参数一般填写默认值false或不填,因为:大多数情况下,都是将事件处理程序添加到时间流的冒泡阶段,这样可以最大限度地兼容各种浏览器,如果不是特别需要,不建议在事件捕获阶段注册事件处理程序。关于捕获和冒泡同时存在的情况下我总结了以下几点:

(1)冒泡且捕获:捕获导致不能进入更低层事件,点击该层的更低层只能触发该捕获层,一般为了不阻断其他事件的触发设置捕获为false。

(2)冒泡但不捕获:执行冒泡顺序,从触发层从内到外执行事件,与事件监听绑定的顺序无关。

(3)若多级包含元素且多个元素都添加事件监听则为了更稳定的执行时间需要:①每个元素的事件监听的捕获都设置为false或不填。②并且在执行函数内阻止冒泡。e.stopPropagation()||e.cancelBubble=true;

4、IE事件处理程序:attachEvent()添加事件,detachEvent()删除事件,由于(IE8-)不支持捕获,所以两种方法只支持两个参数:

第一个参数:事件处理程序函数名称eg:onclick  onmouseover

第二个参数:作为事件处理程序的函数

例如:

var oBox = document.getElementById("container");

oBox.attach("click",fn());

oBox.detach("click",fn());

function fn(){//执行函数}

注意:使用这种方法的事件处理程序的作用域是全局,函数内this指向window而不是事件目标对象,如果要指定事件目标对象可以也使用event.srcElement。能给添加多个,但是执行顺序与添加顺序相反。

5、跨浏览器事件处理程序:   

 var EventUtil = {
addHandle: function(element,type,handle) {
if(element.addEventListener) {
element.addEventListener(type,handle);
}else if(element.attachEvent) {
element.attachEvent("on"+type,handle);
}else {
element["on"+type] = handle;
}
},
removeHandle: function(element,type,handle) {
if(element.removeEventListener) {
element.removeListener(type,handle);
}else if(element.detachEvent) {
element.detachEvent("on"+type,handle);
}else {
element["on"+type] = null;
}
}

}

    EventUtil.addHandle(oBox,"click",fn);
    EventUtil.removeHandle(oBox,"click",fn);

 JS事件流理解

事件捕获和事件冒泡
事件流描述的是从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。 
事件流主要分为两种,即事件捕获和事件冒泡,这二者接受事件处理的顺序不同。假设下面的代码:

<body>
    <div id="outer">
        <div id="inner"></div>
    </div>
</body>


这两个事件流分别的是IE公司和netspace公司提出来的,冒泡事件流支持的浏览器更多。 
冒泡事件流中,事件的传递顺序是从子元素向父元素传递。假设我们给div绑定一个click事件。那么在冒泡事件流中,事件的传递顺序是:inner->outer->body。然而捕获事件流的顺序则截然想法:body->outer->innner。

DOM事件流

DOM2级事件规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。还是以上面的代码为例,单击inner则会按照下面的顺序触发事件:document->html->body->outer->ineer->outer->body->html->document。在DOM事件流中,实际的目标inner在捕获阶段不会接受到事件。这意味着在捕获阶段,事件到outer就停止了,下一个阶段是“处于目标”阶段,于是事件在inner 上发生,并在事件处理中呗看成是冒泡阶段的一部分。然后,冒泡阶段发生,事件又传播回文档。

事件处理程序

响应某个时间的函数叫做事件处理程序。DOM0级的事件处理程序很简单,onclick就是常用的DOM0级事件处理函数,只会在冒泡阶段被处理。 
而DOM2级事件定义了两个方法用于处理置顶和删除事件处理程序的操作addEventListener()和removeEventListener(),所有DOM节点都包含这两个方法,并且它们都接受3个参数:要处理的事件名,作为事件处理的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序,反之则是在事件冒泡阶段处理程序。DOM2级方法添加事件处理程序的好处是可以添加多个事件处理程序,会按照添加顺序被处理(无论是捕获还是冒泡)。 
而IE不同的它有自己的方法attachEvent()和detachEvent,这两个接受相同的两个参数:事件处理程序名称和事件处理程序函数。跨浏览器的事件处理程序
 

var EventUtil = {
    addHandler: function(element,type,handler) {
        if (element.addEventListener) {
            element.addEventListener(type,handler,false);
        }
        else if (element.attachEvent) {
            element.attachEvent('on'+type,handler);
        }
        else {
            element['on'+type] = handler;
        }
    },

    removeHandler: function(element,type,handler) {
        if (element.removeEventListener)
        {
            element.removeEventListener(type,handler,false);
        }
        else(element.detachEvent) {
            element.detachEvent('on' +type,handler);
        }
        else {
            element['on'+type] = null;
        }
    }
}

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值