JavaScript和HTML之间的交互是通过事件实现的。事件,就是文档或者浏览器窗口中发生的一些特定的交互瞬间。可以使用事件处理程序来预订事件,以便在事件发生的时候执行响应的代码。这种观察者模式的模型,使得JavaScript代码与HTML和CSS代码之间形成了松散耦合。

事件流

事件流描述的是从页面中接受事件的顺序。但是值得注意的是,在当年的浏览器大战中的主角们采用的是几乎完全相反的事件流概念。IE的事件流是事件冒泡流,而Netscape Communicator的事件流是事件捕获流

事件冒泡

IE的事件流叫做事件冒泡(event bubbing),即事件右最具体的元素接受,然后逐级向上传播到不具体的元素,以下面的代码为例:

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="btn">点我</div>
</body>
</html>

如果你单击了#btn,那么在IE的页面中,这个事件会如下传播:

div->body->html->document

可以看到,事件首先在div上发生,div就是我们单击的元素。然后事件沿着DOM树向上传播,一直到document对象。

所有的现代浏览器都支持事件冒泡。IE9,Firefox,Chrome和Safari则将事件一直冒泡到window对象。

事件捕获

事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该是最后接收到事件。事件捕获的顾名思义就是在事件到达预定的目标之间捕获它。以上面的代码作为例子,那么单击div的时候会按照与冒泡相反的顺序触发事件。

div->body->html->document

在这个过程中,document对象先接收到click事件,然后事件沿着DOM树依次向下,一直传递到目标元素。

IE9,Firefox,Chrome和Safari都支持事件捕获。“DOM2级事件”规范要求事件应该从document对象开始传播,但实际上这些浏览器都是从window对象开始捕获事件。

DOM事件流

DOM事件流比事件毛婆和事件捕获稍微复杂一点点。它规定的事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。

以前面的代码为例。单击div

事件处理程序

HTML事件处理程序

<input type="button" value="Click" id="go" onclick="showMessage()" />

这玩意儿就是传说中的HTML事件处理程序。最明显的缺点就是:HTML与JavaScript代码紧密耦合。如果要更换事件处理程序,就要同时修改HTML和JavaScript代码。

DOM0级事件处理程序

通过JavaScript制定事件处理程序的传统方法,就是讲一个函数赋值给一个叫做“事件处理程序”的属性。每个元素都有自己的事件处理程序属性,这些属性通常全部都是小写,例如onclick。将事件处理程序设置为一个函数,就可以指定事件处理程序。

var btn=document.getElementById("myBtn");
btn.onclick=function(){
alert("Clicked!");
}

要使用JavaScript指定事件处理程序,必须先获得对象元素的引用,然后为其指定事件处理程序的函数。

事件处理程序是在元素的作用域中运行的,也就是说程序中的this指向的是当前元素。

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

以这种当时添加的事件处理程序会在事件流的冒泡阶段被处理。

通过将事件处理程序属性的值设置成null就可以删除事件处理程序。

btn.onclick=null;

DOM2级事件处理程序

“DOM2级事件”规定了两个方法用于操作事件处理程序:addEventListener()和removeEventListener()。所有的节点都包含这两个方法,接收三个参数:要处理的事件名,作为事件处理程序的函数和一个布尔值。最后的参数如果是true,表示在事件捕获阶段调用事件处理程序,如果是false,表示在事件冒泡阶段调用事件处理程序。

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

DOM0级事件处理程序只能为一个元素添加唯一的某一个事件的处理程序。如果为一个元素添加了两个click的处理程序,后定义的程序会覆盖掉之前定义的程序,其实也就是给变量a多次赋值一样。使用DOM2级事件处理程序的好处之一就是:可以添加多个添加多个事件处理程序。

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

这两个事件处理程序会按照添加的顺序触发。

通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除。通过addEventListener()添加的匿名函数无法移除,因为移除是传入的参数一添加处理程序时使用的参数必须相同

为了最大限度地兼容浏览器,建议在大多数情况下豆浆事件处理程序添加到事件流的冒泡阶段。

IE中的事件处理程序

IE中有类似于DOM的两个方法:attachEvent()和detachEvent()。这两个方法接受两个参数:事件处理程序名称和事件处理程序函数。attachEvent()添加的事件处理程序都会添加到冒泡阶段

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

要注意哟,第一个参数是“onclick”而不是“click”。前面说到,在DOM0级事件中,事件处理程序的作用域是元素的作用域,而在使用attachEvent()时,作用域变成了全局作用域,此时this等于window

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

与addEventListener()一样,attachEvent()也可以用来为一个元素天剑多个事件处理程序,不过与DOM方法不同的是,事件处理程序不是按照添加的顺序执行,而是以相反的顺序执行。

可以使用detachEvent()移除使用attachEvent()添加的事件处理程序。与DOM方法一样必须提供相同的参数,添加的匿名函数不能被移除。

因此跨浏览器的事件处理程序可以这么写:

(来自《JavaScript高级程序设计》)

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 if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
}
};
var btn = document.getElementById("myBtn");
var handler = function () {
alert("Clicked");
};
EventUtil.addHandler(btn, "click", handler);
EventUtil.removeHandler(btn, "click", handler);

参考:《JavaScript高级程序设计》

JavaScript中的事件处理程序的更多相关文章

  1. javascript中 IE事件处理程序中try catch用法

    本例是学习中笔记 望指正批评! <input id='b1' type='button' value='按钮'/> <script> window.onload=functio ...

  2. 学习javascript中的事件——事件处理程序

    事件就是用户或浏览器自身执行的某种动作.诸如 click.load 和 mouseover ,都是事件的名字.而响应某个事件的函数就叫做事件处理程序(或事件侦听器).事件处理程序的名字以“on”开头, ...

  3. JavaScript中的事件对象

    JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...

  4. JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获

    先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...

  5. 了解javascript中的事件(二)

    本文目录如下: 零.寒暄 一.事件的分类 二.事件代理 2.1 问题引出 2.2 什么是事件代理 2.3 完整示例 二.事件代理 三.事件代理思想的用处 四.总结 零.寒暄 这篇博客本该出现在两个月以 ...

  6. JavaScript中对事件简单的理解(1)

    事件(event) 1.什么是JavaScript事件? 事件是文档或浏览器中发生的特定交互瞬间. 2.事件流 事件流描述的是从页面中接受事件的顺序,包含IE提出的事件冒泡流与Netscape提出的事 ...

  7. 说说JavaScript中的事件模型

    1.javascript中为元素添加事件处理程序的方法有以下几种方式,可以为javascript元素添加事件处理程序 (1) 直接将事件处理代码写在html中(2) 定义一个函数,赋值给html元素的 ...

  8. JavaScript中对事件简单的理解

    事件(event) 1.什么是JavaScript事件? 事件是文档或浏览器中发生的特定交互瞬间. 2.事件流 事件流描述的是从页面中接受事件的顺序,包含IE提出的事件冒泡流与Netscape提出的事 ...

  9. javascript 中的事件机制

    1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...

随机推荐

  1. C# 中使用Newtonsoft.Json 处理JSON数据 绝对能用

    当你搜到这篇文章是幸运的,因为之前我遇到这个问题 主要是 Newtonsoft.Json 版本不一 且网上各种文章 都是复制的 并不说明版本的问题 这里我就不说什么版本的问题了,总之必须使用我这个DL ...

  2. yii2.0 控制器方法 视图表单 Form表单处理

    假设我们在ArticleController.php下面的actionForm方法中来处理提交的表单 新建立一个 views/Article/article-form.php文件用来作为输入表单 &l ...

  3. [C++]Infinite House of Pancakes——Google Code Jam 2015 Qualification Round

    Problem It’s opening night at the opera, and your friend is the prima donna (the lead female singer) ...

  4. .NET(C#):XmlArrayItem特性和XmlElement特性在序列化数组的差别

    原文http://www.cnblogs.com/mgen/archive/2011/12/04/2276238.html 比如这样一个类,我们用XmlArrayItem特性标明数组内出现的元素类型: ...

  5. 如何解决dns解析故障

    在实际应用过程中可能会遇到DNS解析错误的问题,就是说当我们访问一个域名时无法完成将其解析到IP地址的工作,而直接输入网站IP却可以正常访问,这就是因为DNS解析出现故障造成的.这个现象发生的机率比较 ...

  6. 成都Uber优步司机快速注册攻略(外地车牌也可加入,不用现场培训)

    我加入Uber司机有一段时间了,有一些经验和感想分享给大家,让大家少走些弯路.目前加入优步不收取任何费用,不需要抢单,时间安排自由灵活,使用便捷,深受大众喜爱. 加入人民优步拼车条件:购买运行5年之内 ...

  7. Android 自己主动化測试之------ Monkey工具

    尽管 一般公司都有专门的測试人员,可是有时候 免不了 我们既要去开发产品,也要去測试产品,測试产品.有些机械化的 点界面的操作,谷歌已经给我们提供了工具.Monkey, 猴子測试. 什么是Monkey ...

  8. c语言中-----分配内存函数

    原型: void * realloc(void *p, size_t  size); realloc 可以对给定的指针所指的空间进行扩大 或者 缩小, 原有内存的数据保持不变.当然,对于缩小,则缩小部 ...

  9. XML 文档解析操作

    sing System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security; ...

  10. JavaScript基础(简介、语法)

    一.JavaScript简介 1.JavaScript是个什么东西? 它是个脚本语言,需要有宿主文件,它的宿主文件是HTML文件. 2.它与Java什么关系? 没有什么直接的联系,Java是Sun公司 ...