欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript中为事件指定处理程序的五种方式分析

程序员文章站 2022-05-01 09:41:05
本文实例讲述了javascript中为事件指定处理程序的五种方式。分享给大家供大家参考,具体如下: javascript和html之间的交互是通过事件实现的。 ie9、...

本文实例讲述了javascript中为事件指定处理程序的五种方式。分享给大家供大家参考,具体如下:

javascript和html之间的交互是通过事件实现的。

ie9、firefox、opera、sarifi、chrome都已经实现了dom2级事件模块的核心部分,ie8是最后一个仍然使用其专有事件系统的主要浏览器。

事件流:

事件流描述的是从页面中接受事件的顺序,但ie和netscape却提出了完全相反的事件流的概念,ie的事件流是事件冒泡流,而netscape的事件流是事件捕获流。

1) 事件冒泡

事件开始时由最具体的元素(文档中嵌套层次最深的那个节点接收,然后逐级向上传播到较为不具体的节点(文档)。

不支持事件冒泡的事件:blurfocusloadunload

2) 事件捕获

不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于事件到达预定目标之前捕获它。

虽然ie9、safari、chrome、firefox、opera都支持事件捕获和事件冒泡,但ie8及其更早版本只支持事件冒泡,不支持事件捕获,因此。建议使用事件冒泡,在有特殊需要的时候再使用事件捕获。

dom事件流:

dom2级事件规定的事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。实际上,在事件捕获阶段预定目标不会接收到事件,处于目标阶段事件在预定目标上发生。事件处理中,处于目标阶段被看成事件冒泡阶段的一部分。但是,即使“dom2级事件”规范明确要求捕获阶段不会涉及事件目标,但ie9、 safari、chrome、firefox和opera9.5及更高版本都会在捕获阶段触发事件对象上的事件,结果是有两个机会在目标对象上操作事 件。

ie9、firefox、opera、sarifi、chrome都支持dom事件流,ie8及其更早版本不支持dom事件流。

事件处理程序:

事件就是用户或浏览器自身执行的某种动作,而响应某个事件的函数就是事件处理程序(或事件侦听器),事件处理程序的名字以“on”开头。

javascript中有五种事件处理程序方式:

1) html事件处理程序

每种事件都可以使用一个与相应事件处理程序同名的html特性来指定,特性的值可以是能够执行的javascript代码,也可以是函数。函数中有一个局部变量event,通过event变量可以访问事件对象;在函数内部,this值等于事件的目标元素。

在html中指定事件处理程序的几个缺点:

① 时差问题:用户可能在html元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件,如用户在解析事件处理函数之前就触发事件。为此,很多html事件处理程序都会封装在一个try-catch块中,以便及时捕获错误,以免错误抛出被用户看到。

② 扩展事件处理程序的作用域链在不同浏览器中会导致不同的结果。不同javascript引擎遵循的标识符解析规则略有差异,很有可能会在访问非限定对象成员时出错。

③ html代码与javascript代码紧密耦合,更换事件处理程序需要改动html代码与javascript代码。

2) dom0级事件处理程序

通过javascript指定事件处理程序的传统方式,将一个函数赋值给一个事件处理程序属性。使用dom0级方法指定的事件处理程序被认为是元素的方法,因此this引用当前元素。

dom0级事件处理程序的优势:

① 简单;

② 跨浏览器

可以通过将事件处理程序的值设置为null来删除通过dom0级方法指定的事件处理程序。

3) dom2级事件处理程序

dom2级事件定义了两种方法,用于指定和删除事件处理程序的操作:addeventlistener()removeeventlistener(),它们都接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(true表示在捕获阶段调用事件处理程序,false表示在冒泡阶段调用事件处理程序)。

dom2级事件处理程序的优势:

可以添加多个事件处理程序,它们会按照添加它们的顺序触发。

通过addeventlistener()添加的事件处理程序只能用removeeventlistener()来移除,但要求移除时传入的参数与添加事件处理程序时使用的参数相同,因此通过addeventlistener()添加的匿名函数将无法移除,需要给removeeventlistener()传入addeventlistener()中命名的函数才能正常移除。

4) ie事件处理程序

ie事件定义了两个方法:attachevent()detachevent(),它们都接收2个参数:要处理的事件名、作为事件处理程序的函数.由于ie8及其更早版本只支持事件冒泡,所以通过attachevent()添加的事件处理程序都会被添加到冒泡阶段。

注意:通过ie的attachevent()添加的事件处理程序的名字以“on”开头,而通过dom的addeventlistener()添加的名字不是。

在ie中使用attachevent()与使用dom0级方法的主要区别:

事件处理程序的作用域不同。在ie中使用attachevent(),事件处理程序会在全局作用域中运行,因此this等于window;而使用dom0级方法,事件处理程序会在其所属元素的作用域中运行。

在ie中使用attachevent()与使用dom2级方法的区别:

添加多个事件处理程序的执行顺序不同。在ie中使用attachevent(),可以添加多个事件处理程序,它们会按照添加它们的相反顺序触发;在dom中使用addeventlistener(),可以添加多个事件处理程序,但它们会按照添加它们的顺序触发。

通过attachevent()添加的事件处理程序只能用detachevent()来移除,但要求移除时传入的参数与添加事件处理程序时使用的参数相同,因此通过attachevent()添加的匿名函数将无法移除,需要给detachevent()传入attachevent()中命名的函数才能正常移除。

5) 跨浏览器的事件处理程序

要保证事件处理程序的代码在大多数浏览器下一致地运行,只需关注冒泡阶段。

视情况分别使用dom2级方法、ie方法、dom0级方法来添加和移除事件,addhandler()removehandler()方法属于eventutil对象。

① 先检测传入的元素是否存在dom2级方法(传入的第三个参数为false以表示冒泡阶段);

② 再检测传入的元素是否存在ie的方法;

③ 最后检测传入的元素是否存在dom0级方法(使用方括号语法将属性名指定为事件处理程序)。

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;
  }
}

ps:关于javascript事件说明可参考本站javascript事件与功能说明大全

更多关于javascript相关内容感兴趣的读者可查看本站专题:《javascript事件相关操作与技巧大全》、《javascript页面元素操作技巧总结》、《javascript操作dom技巧总结》、《javascript查找算法技巧总结》、《javascript数据结构与算法技巧总结》、《javascript遍历算法与技巧总结》及《javascript错误与调试技巧总结

希望本文所述对大家javascript程序设计有所帮助。