知识要点

客户端JavaScript程序采用了异步事件驱动变成模型(13.3.2节)。这种风格并不只应用于web编程,所有使用图形用户界面的应用程序都采用它,它们静待某些事件发生,然后响应。

事件就是web浏览器通知应用程序发生什么事情。它不是JavaScript对象,不会出现在程序源代码中。当然,有些事件相关的对象会出现在源代码中。

事件类型是一个用来说明发生什么类型事件的字符串。由于只是个字符串,所以也可以叫事件名字。

事件目标是发生的事件或与之相关的对象。事件必须同时致命类型和目标。例如window上的load事件或<button>元素的click事件。在客户端JavaScript中,Window、Document和Element对象是最常见的事件目标。有些事件是由其他类型的对象触发,例如18章的由XHR对象触发的readystatechange事件。

事件处理程序或事件监听程序是处理或响应事件的函数。

事件对象是与特定事件相关且包含有关该事件详细信息的对象。事件对象作为参数传递给事件处理程序函数(IE8及以前版本不一样)。所有事件对象都有用来指定事件类型的type属性和指定事件目标的target属性(IE8前的srcElement)。每个事件类型都为其相关事件对象定义一组属性,例如鼠标事件有指针坐标,很多只有type和target,没有更详细的属性。

事件传播是浏览器决定哪个对象触发其事件处理程序的过程。对于单个对象的特定事件(比如Window对象的load事件),必须是不能传播的。当文档元素发生在某个类型的事件时,会发生冒泡,还有事件捕获(IE8及以前不支持,所以少用)。

事件处理程序可以通过返回一个适当的值、调用事件对象的某个方法或设置对象的某个属性来阻止默认操作的发生。比如超链接的click事件可以阻止加载新页面。

1.事件类型

1.1.传统事件类型

表单事件

通过事件处理程序能取消submit和reset事件的默认操作,某些click事件也是如此。focus和blur事件不会冒泡,但其他所有表单事件都可以。ie定义了focusin和focusout事件可以冒泡,它们可以用于替代focus和blur事件。

无论用户何时输入文字(通过键盘或剪切和粘贴)到textarea和其他文本输入表单元素,除ie外的浏览器都会触发input事件。不像change事件,每次文字插入都会触发input事件,遗憾的是,input事件的事件对象没有指定输入文字的内容(textinput事件将会成为这个事件的有用替代方案。)

Window事件

Window是指事件的发生与浏览器本身而非窗口中显示的任何特定文档内容相关,但是,这些事件中有一些会和文档元素上发生的事件同名。

window对象的onerror属性有点像事件处理程序,当javascript出错时会触发他。但是,它不是真正的事件处理程序,因为它能用不同的参数来调用(14.6节)。

像<img>元素这样的单个文档元素也能为load和error事件注册处理程序。当外部资源(例如图片)完全加载或发生阻止加载的错误时就会触发它们。某些浏览器也支持也支持abort事件,当图片(或其他网络资源)因为用户停止加载进程而导致失败就会触发它.

鼠标事件

传递给鼠标事件处理的事件对象有属性集,它们描述了当事件发生时鼠标的位置和按键状态,也指明了当时是否有任何辅助键按下。clientX和clientY属性指定了鼠标在窗口坐标中的位置,button和which属性指定了按下的鼠标键是哪个。当键盘辅助键按下时,对应的属性altkey、ctrlKey、metaKey和shiftKey会设置为true。而对于click事件,detail属性指定了其是单击、双击还是三击。

键盘事件

无论任何文档元素获得键盘焦点都会触发键盘事件,并且他们会冒泡到Document和window对象。如果没有元素获得焦点,可以直接在文档上触发事件。传递给键盘事件处理程序的事件对象有keyCode字段。它指定按下或释放的键是哪个,除了keyCode,键盘事件对象也有altKey,ctrlKey、metaKey和shiftKey,描述键盘辅助建的状态。

1.2.DOM事件

新DOM标准通过在事件对象中加入新的key和char属性来简化keydown、keyup和keypress事件,这些属性都是字符串。

1.3.HTML5事件

离线web应用还定义了大量其他事件来通知应用:

2.注册事件处理程序

有两种基本方式:第一种,给事件目标对象或文档元素设置属性。第二种方式,是将事件处理程序传递给对象或元素的一个方法,每种技术都有两个版本。可以在javascript代码中设置事件处理程序为对象属性,或对于文档元素,可以在html中直接设置相应属性。对于通过方法调用的处理程序注册,有一个标准方法,命名为addEventListener,除IE8及以前版本之外,所有浏览器都支持这个方式,而ie9之前的IE版本支持的是一个叫attachEvent的不同方法。

2.2.设置HTML标签属性为事件处理程序

某些事件类型通常直接在浏览器而非任何特定文档元素上触发。在javascipt中,这些事件处理程序在window对象上注册。在html中,会把他们放在body标签上,但浏览器会在window对象上注册它们

在指定一串JavaScript代码作为HTML事件处理程序属性的值时,浏览器会把代码串转换为类似如下的函数中:

function(event){
with(document){
with(this.form || {}){
with(this){
/*这里是编码*/
}
}
}
}

3.事件处理程序的调用

3.1.事件处理程序的参数

通常调用事件处理程序时把事件对象作为他们的一个参数(有一个例外)。事件对象的属性提供了有关事件的详细信息,例如,type属性指定了发生的类型。在IE8及以前版本中,通过设置属性注册处理程序,当调用它们时并未传递事件对象,取而代之,需要通过全局对象window.event来获得事件对象

function handler(event){
var event=event||window.event;
}

向使用attachEvent注册的事件处理程序传递事件对象,但它们也能使用window.event。

17.2.2节,当通过设置HTML属性注册事件处理程序时,浏览器会把javascript编码转换到一个函数中。非IE浏览器使用event参数来构造函数,而IE在构造函数时没有有要求参数。如果在这样的函数中使用event标识符,那么引用的正是Window.event.在这两种情况下,HTML事件处理程序都能作为event引用事件对象。

3.2.事件处理程序的运行环境

当使用addEventListener注册时,调用的处理程序使用事件目标作为它们的this值。但是,对于attachEvent来讲这是不对的:使用attachEvent注册的处理程序作为函数调用,它们的this值是全局对象(window)。可以用如下代码来解决这个问题:

/*
*在指定的事件目标上注册用于处理指定类型事件的指定处理程序函数
*确保处理程序一直作为事件目标的方法调用
*/
function addEvent(target,type,handler){
if(target.addEventListener){
target.addEventListener(type,handler,fasle);
}
else{
target.attachEvent("on"+type,function(event){
return handler.call(target,event);
//把处理程序作为事件目标的方法调用,传递事件对象
})
}
}

注意使用这个方法注册的事件处理程序不能删除,因为传递给attchEvent的包装函数没有保留下来传递给detachEvent。

3.3.事件处理程序的作用域

它们在其定义时的作用域而非调用时的作用域中执行,并且它们能存取那个作用域中的任何一个本地变量。但是通过HTML属性来注册事件处理程序是一个例外,它们被转换为能存取全局变量的顶级函数而非任何本地变量。但是由于历史原因,它们运行在一个修改后的作用域链中,通过HTML属性定义的事件处理程序能好像本地变量一样使用目标对象,容器<form>对象(如果有)和Document对象的属性。

HTML属性最不自然的地方包括冗长的代码串和修改会的作用域链允许有用的快捷方式,可以使用tagName替代this.tagName,使用getElementById()替代document.getElementById()。并且,对于<form>中的文档元素,能通过ID引用任何其他的表单元素,例如zicode替代this.form.zipcode。

另一方面,HTML事件处理程序中修改的作用域链是陷阱之源,因为作用域链中每个对象的属性在全局对象中都有相同名字的属性。例如Document对象定义(很少使用)open()方法,因此HTML事件处理程序想调用Window对象的open方法就必须显示地调用window.open而不是open。表单有类似的问题但破坏性更大,因为表达元素的名字和ID在包含的表单元素上定义属性。例如表单包含一个ID是“location”的元素,那么要是表单的所有HTML事件处理程序想引用window的location对象,就必须使用window.location而不能是location。

3.4.事件处理程序的返回值

通过设置对象属性或HTML属性注册事件处理程序的返回值有时是非常有意义的。

3.7.事件取消

function cancelHandle(event){
var event = event || window.event;//用于IE
/*处理事件的代码*/
//取消默认行为
if(event.preventDefault)event.preventDefault();
if(event.returnValue)event.returnValue = false;
return false; //用于处理使用对象属性注册的处理程序
}

5.鼠标事件

7.拖放事件

http://www.w3school.com.cn/html5/html_5_draganddrop.asp

JavaScript权威指南--事件处理的更多相关文章

  1. 《JavaScript权威指南(第6版)(中文版)》PDF

    简介自1996年以来,JavaScript的:权威指南已为JavaScript圣经程序员,程序员指南和全面的参考,以核心语言和客户端JavaScript API的Web浏览器定义.第6版包括HTML5 ...

  2. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  3. JavaScript权威指南 - 对象

    JavaScript对象可以看作是属性的无序集合,每个属性就是一个键值对,可增可删. JavaScript中的所有事物都是对象:字符串.数字.数组.日期,等等. JavaScript对象除了可以保持自 ...

  4. JavaScript权威指南 - 数组

    JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...

  5. 《javascript权威指南》读书笔记——第二篇

    <javascript权威指南>读书笔记——第二篇 金刚 javascript js javascript权威指南 今天是今年的196天,分享今天的读书笔记. 第2章 词法结构 2.1 字 ...

  6. 《javascript权威指南》读书笔记——第一篇

    <javascript权威指南>读书笔记——第一篇 金刚 javascript js javascript权威指南 由于最近想系统学习下javascript,所以开始在kindle上看这本 ...

  7. Javascript权威指南

    一.数字写法 3.14 2345.789 .333333333333333333 6.02e23 // 6.02 × 10 23 1.4738223E-32 // 1.4738223 × 10 −32 ...

  8. 《JavaScript权威指南 第六版 中文版》(一)

    <JavaScript权威指南 第六版 中文版> 第二章 词法结构 2.1字符集 JavaScript是使用Unicode字符集编码写的. 2.1.1区分大小写 JavaScript是区分 ...

  9. javascript权威指南(中文版)中的一些错误(一)

    本人目前正在学习js,使用的是javascript权威指南(中文版),学习的时候发现一些细节上的错误,若是我的错误,欢迎指正 1.P11------多了“我们称为 原文为 return Math.sq ...

随机推荐

  1. 优化改良版:数组,List,等集合需要加逗号或其它符合转成字符串

    大家经常需要数组加逗号拼接成字符串的情况传统作法就是写for,foreach拼接, 现给出优化改良版数组,List,等集合需要加逗号或其它符合转成字符串方法: List<string> l ...

  2. appium记录

    npm uninstall appium -g npm install -g cnpm --registry=https://registry.npm.taobao.org cnpm install ...

  3. 英语笔记-some words about description of girl

     what did you learn from your last class?20:09:07abc360.Draven/PHH-HA04 ☠ 2018/4/9 20:09:07 poop20:1 ...

  4. Oracle和sql server中复制表结构和表数据的sql语句

    在Oracle和sql server中,如何从一个已知的旧表,来复制新生成一个新的表,如果要复制旧表结构和表数据,对应的sql语句该如何写呢?刚好阿堂这两天用到了,就顺便把它收集汇总一下,供朋友们参考 ...

  5. python之路----验证客户端合法性

    验证客户端链接的合法性 import os import hmac import socket secret_key = b'egg' sk = socket.socket() sk.bind(('1 ...

  6. python之路----模块调用

    如何使用模块? 1 import 示例文件:自定义模块my_module.py,文件名my_module.py,模块名my_module #my_module.py print('from the m ...

  7. C站投稿映兔源的方法

    (因映兔源也不太稳定了,所以不建议映兔上传,正在找其他视频源代替映兔,另外等待C站大大们的webbt源)(20180226) 测试换文件格式后会不会失效,能坚持几天?http://www.cnblog ...

  8. python的时间处理-time模块

    time模块 时间的表示方法有三种: 时间戳:表示的是从1970年1月1日0点至今的秒数 格式化字符串表示:这种表示更习惯我们通常的读法,如2018-04-24 00:00:00 格式化元祖表示:是一 ...

  9. php json_decode返回null

    在使用json_decode函数想把json串转化为数组的时候,出现了null,当时还以为是因为json对字符串的长度有限制,还以为是因为两边少了引号,经过多次处理,发现都没有效果. 百度各种帖子,发 ...

  10. 使整个页面变灰的css代码

    * { filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=); -webkit-filter: grayscale(%); - ...