JavaScript权威指南--事件处理

知识要点

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

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

事件类型是一个用来讲明发生什么类型事件的字符串。因为只是个字符串,因此也能够叫事件名字。html5

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

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

事件对象是与特定事件相关且包含有关该事件详细信息的对象事件对象做为参数传递给事件处理程序函数(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

相关文章
相关标签/搜索