【写在前面】近期一直在看js的基础,毕竟jquery尽管好用,总归是用着别人写的,仅仅会用api不如搞清楚实现的原理。

等把js基础巩固好了一定要去读jquery的源代码。

事件流

事件流描写叙述的是从页面中接收事件的顺序。js中有两种事件流,冒泡流和捕获流。两种流的名称都非常形象。在由节点构成的一颗html树上面,冒泡流指事件開始时候由最详细的元素最先接收,然后逐级传播到最不详细的节点,比方在例如以下文档中:

<!doctype html>
<html>
<head></head>
<body>
<div></div>
</body>
</html>

当单击div时,事件首先在div上响应。然后传到body元素上,然后传到html元素上,最后传到document对象。

捕获流正好相反,最先响应的是document对象。然后沿dom树依次向下,到html,到body,最后到实际目标,也就是div。

老版浏览器并不支持捕获流,冒泡流也非常符合我们对事件传播的理解,因此我们很多其它使用的是冒泡流。

事件处理的几种方法

在js的事件处理中定义了非常多种事件,事件名称是指详细的某种动作,比方click、load、mouseover等都是事件的名称。

响应某个事件的函数叫事件处理程序,事件处理程序的名字是以on开头的,因此click事件的事件处理程序就是onclick,load事件的事件处理程序就是onload。

标签内绑定

通过设置标签的属性能够为节点十分方便地绑定事件。如:

<input type="button" value="button" onclick="alert('button按下')">

也能够调用其它地方定义的脚本:

<script>
function showMessage(){
alert("button按下");
}
</script>
...
<input type="button" value="button" onclick="showMessage()">

使用直接绑定有两个特别的地方,其一是会创建一个封装元素属性的函数。这个函数中有一个局部变量event。也就是事件对象:

<!--输出'click'-->
<input type="button" value="button" onclick="showMessage(event.type)">

事件产生时,event对象自己主动传递到showMessage函数中,通过这个对象我们能够訪问到事件对象的非常多属性。另外在事件处理程序内部,this指代事件的目标元素,比方

<!--输出'button'-->
<input type="button" value="button" onclick="showMessage(this.value)">

另外当当前元素是一个表单元素时,则作用域中还会包括表单元素的入口,也就是说在事件处理程序中能够訪问其它表单元素。比如

<form>
<input type="text" name="username"/>
<input type="button" value="button" onclick="alert(username.value)">
</form>

这样能够直接输出username中的值。

然而通过这样的方式加入的事件处理尽管直观方便,但有非常多坏处:

(1)由于页面载入顺序是从上往下,假设绑定的脚本写在html以下,可能用户点击元素的时候脚本还未运行,造成用户点半天没反应,如:

<input type="button" value="button" onclick="showMessage()">
...
...//非常多内容
...
<script>
function showMessage(){
//...
}
</script>

(2)html和js代码紧密结合,比方showMessage这种方法,假设界面内非常多元素都通过这样的方式绑定了这种方法。那么假设某一刻想给这个函数换一个名字时,你须要同一时候修改非常多处地方,相当麻烦。

DOM0级处理程序

另外一种方式是在js中为元素绑定事件,通过在js中获取元素。然后给其指定事件:

var btn = document.getElementById("button");
btn.onclick = function(){
alert(this.id);
}

通过DOM0级方法指定的程序被觉得是元素的方法,所以上述代码运行后,按下元素弹出的将是button的id,能够通过this获取该元素全部的属性和方法。

须要删除通过DOM0级方法指定的事件处理程序,仅仅需将该属性值设为null就可以:

btn.onclick = null;

须要注意的是通过这样的方式不能为元素加入反复事件,多次为onclick赋值仅仅有最后一个是有效的,比方

btn.onclick = function(){
alert("first");
}
btn.onclick = function(){
alert("second");
}

最后单击button的时候仅仅会输出second。

DOM2级处理程序

IE9、Firefox、chrome、safari和opera支持DOM2级事件处理程序

“DOM2级事件”定义了两个方法,用于指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。全部DOM节点都有这种方法,并接收3个參数:事件名、事件处理函数和一个布尔值。这个布尔值代表了是使用捕获还是冒泡。true代表在捕获阶段处理。false代表在冒泡阶段处理。不填默认是false。

var btn = document.getElementById("button");
btn.addEventListener("click", function(){
//...
}, false);

和DOM0级事件处理不同。通过这样的方法绑定的事件处理能够多次加入,比方

var btn = document.getElementById("button");
btn.addEventListener("click", function(){
alert("first");
}, false);
btn.addEventListener("click", function(){
alert(this.id);
}, false);

并且在函数内this相同指代目标元素,点击button后会先输出first。再输出该btn的id。

通过addEventListener加入的事件仅仅能通过removeEventListener移除,并且參数必须一样(三个參数一模一样),这代表使用匿名函数绑定的事件是无法移除的,最好将事件处理函数单独定义。

btn.addEventListener("click", function(){
alert("first");
}, false);
btn.removeEventListener("click", function(){
alert("first");
}, false); //没有效果 btn.addEventListener("click", showMessage, false);
btn.removeEventListener("click", showMessage, false); //移除成功

IE事件处理程序

IE中单独实现了与DOM2级事件处理中类似的两个方法:attachEvent和detachEvent()。

这两个方法接收两个參数:事件处理程序名称和事件处理函数。由于IE8及更早版本号仅仅支持事件冒泡,所以通过这样的方式加入的事件处理程序都会被加入在事件冒泡阶段。

var btn = document.getElementById("button");
btn.attachEvent("onclick", function(){ //注意是onclick
alert("first");
});

IE事件处理同之前的其它方式有两个差别,第一,IE的事件处理程序会在全局环境下运行。

这代表在当中使用this会等于window。

var btn = document.getElementById("button");
btn.attachEvent("onclick", function(){
alert(this === window); //true
});

第二。多次加入的事件处理函数按加入的相反顺序运行,比方

var btn = document.getElementById("button");
btn.attachEvent("onclick", function(){
alert("first");
});
btn.attachEvent("onclick", function(){
alert("second");
});

当按下button时。将先输出second,然后才输出first。

要移除事件的方式同DOM2级类似,调用detachEvent然后传如相同參数就可以。

编写跨浏览器的事件处理程序

上面提到IE和其它浏览器在处理事件上还是存在一些差异的,能够编写一个EventUtil对象,来将加入事件和移除事件封装起来。

实现方式是先推断是否支持DOM2级处理。假设不支持採用IE方法。假设都不支持最后採用DOM0级方法。

var EventUtil = {
//加入事件
addHandler: function(element, type, handler){
if(element.addEventListener){
//支持DOM2级
element.addEventListener(type, element, handler);
}else if(element.attachEvent){
//IE事件处理,注意on前缀
element.attachEvent("on" + type, handler);
}else{
//DOM0级
element["on" + type] = handler;
}
},
//移除事件
removeHandler: function(){
if(element.removeEventListener){
//支持DOM2级
element.removeEventListener(type, element, handler);
}else if(element.detachEvent){
//IE事件处理,注意on前缀
element.detachEvent("on" + type, handler);
}else{
//DOM0级
element["on" + type] = null;
}
}
}

javascript 事件处理的更多相关文章

  1. javascript事件处理解析

    一.什么是事件!(w3c解释) 事件是可以被 JavaScript 侦测到的行为. JavaScript 使我们有能力创建动态页面.事件是可以被 JavaScript 侦测到的行为. 网页中的每个元素 ...

  2. Javascript事件处理进阶

    这篇文章是我在看乌龟书<编写可维护的Javascript>发现的一篇写的非常好的章节,在这里我并不会教大家什么是绑定事件等比较基础的事.有兴趣了解DOM事件的同学们,可以去w3cschoo ...

  3. JavaScript事件处理的三种方式(转)

    一.什么是JavaScript事件? 事件(Event)是JavaScript应用跳动的心脏,也是把所有东西粘在一起的胶水,当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了. 事件可能是用 ...

  4. 使用AmplifyJS和JQuery编写更好更优雅的javascript事件处理代码

    事件(或消息)是一种经常使用的软件设计模式.可以减少消息处理者和消息公布者的之间的耦合,比方J2EE里面的JMS规范.设计模式中的观察者模式(也叫公布/订阅模式).这对于javascript代码相同适 ...

  5. 私人定制javascript事件处理机制(浅谈)

    看到园子里关于事件监听发表的文章,我都有点不好意思写了.不过想想我的题目以私人定制作开头也就妥妥地写吧. 事件相关概念 1.事件类型 发生事件的字符串 有传统事件类型 比如表单.window事件等 D ...

  6. javascript——事件处理模型(DOM 和 IE)

    javascript的事件处理模型分为 DOM事件处理模型和 IE事件处理模型. 一.DOM事件流模型 DOM事件流分为三个阶段:捕获阶段.目标阶段.冒泡阶段. 捕获阶段:自上而下,由document ...

  7. 【WIP】客户端JavaScript 事件处理

    创建: 2017/10/15 完成: 2017/10/15   更新: 2017/11/04 加粗事件的参数 更新: 2017/12/12 增加事件处理时获取事件对象的方法 更新: 2019/05/2 ...

  8. javascript——事件处理

    <script type="text/javascript"> function EventUtil() { var _self = this; ///添加事件 var ...

  9. JavaScript事件处理

    客户端javascript程序采用了异步事件驱动程序,在这种程序设计风格下,当文档,浏览器,元素,或与之相关的对象发生某些有趣的事件时,web浏览器就会产生事件.事件本身不是javascript对象. ...

随机推荐

  1. fourinone分布式缓存研究和Redis分布式缓存研究

    最近在写一个天气数据推送的项目,准备用缓存来存储数据.下面分别介绍一下fourinone分布式缓存和Redis分布式缓存,然后对二者进行对比,以供大家参考. 1  fourinone分布式缓存特性 1 ...

  2. 使用GridBagLayout控制行列的高度和宽度

    摘自http://bbs.csdn.net/topics/340189065使用GridBagLayout控制行列的高度和宽度 gridwidth 指定组件显示区域的某一行中的单元格数. 默认值1,水 ...

  3. Unity扩展让枚举视图中变成多选框

    如图: 定义属性描述特性(因为没有描述的数据,让绘制类去绘制所以为空) using UnityEngine; using System.Collections; public class EnumFl ...

  4. 本人对于JavaScript的一些总结

    类型.值和变量 1.原始类型   数字.字符串和布尔   null空  undefined未定义 2.对象类型 3.类  Array  Function Date RegExp  Error 4.js ...

  5. 【Unity3d】【项目学习心得】从资源server下载资源(一)

    项目里面的很多资源都是从资源server载入的,这样子能够减小client的包大小. 所以我们须要一个专门的类来管理下载资源. 资源分非常多类型,如:json表,txt文件,image文件,二进制文件 ...

  6. Visual Studio® 2010 Web Deployment Projects站点编译生成bin同时发表插件

    VS2010环境下: 1.Visual Studio® 2010 Web Deployment Projects下载地址:        http://www.microsoft.com/downlo ...

  7. 这个更新需要花去 50.6 M 磁盘上总计 /boot 的空间。请在 7737k 磁盘上留出 /boot 空间。清空您的回收站和临时文件,用“sudo apt-get clean

    系统升级会下载多余的内核,删除即可. 1.命令:dpkg --get-selections|grep linux             //带image的为系统内核 2.命令:   uname -a ...

  8. T - 阿牛的EOF牛肉串(第二季水)

    Description          今年的ACM暑期集训队一共有18人,分为6支队伍.其中有一个叫做EOF的队伍,由04级的阿牛.XC以及05级的COY组成.在共同的集训生活中,大家建立了深厚的 ...

  9. 设计模式之桥接模式(Bridge)--结构模型

    1.意图 将抽象部分与它的实现部分分离,使它们可以独立地变化. 2.适用性 你不希望在抽象和它的实现部分之间有一个固定的绑定关系. 类的抽象与它的实现都应该可以通过子类的方式加以扩展. 抽象部分与实现 ...

  10. activity的生命周期详解

    刚在看mars老师的视频,看到activity的生命周期,就看了一下,总结了一下.下面是各函数的调用时机 为了更清楚的看清楚工作的具体过程,举例如下: ,建立两个activity,一个main,一个a ...