关于js事件5种事件处理程序的详解

先放上整理的思维导图(好丑)
https://blog.csdn.net/weixin_37861326/article/details/81565566
在这里插入图片描述

一.什么是事件处理程序

当特定的操作发生时,就会发生事件。把事件处理程序关联到事件发生时要处理的代码上,就提供了在事件发生时捕获事件并执行相应代码的方式。就像设置闹钟,当某个事件发生时,触动事件处理程序。

二.格式:on+要处理的事件

三.各种方法

html事件处理程序

某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML 特性来指定。这个特性的值应该是能够执行的JavaScript 代码。例如,要在按钮被单击时执行一些JavaScript,可以像下面这样编写代码:

<input type="button" value="Click Me" οnclick="alert('Clicked')" />

也可以调用在页面其他地方定义的脚本

<script type="text/javascript">
function showMessage(){
alert("Hello world!");
}
</script>
<input type="button" value="Click Me" οnclick="showMessage()" />

在这个例子中,单击按钮就会调用showMessage()函数。这个函数是在一个独立的
<script>元素中定义的,当然也可以被包含在一个外部文件中。

事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码。

这样指定事件处理程序具有一些独到之处

首先,这样会创建一个封装着元素属性值的函数。这个函数中有一个局部变量event,也就是事件对象:

<div οnclick="alert(event.type)">event type</div>   // click

通过event 变量,可以直接访问事件对象,你不用自己定义它,也不用从函数的参数列表中读取。
在这个函数内部,this 值等于事件的目标元素,例如:

<input type="button" value="Click Me" οnclick="alert(this.value)">  // click me

dom0级事件处理程序

JavaScript 指定事件处理程序的传统方式,就是将一个函数赋值 给一个 事件处理程序属性。
原因一是简单,二是具有跨浏览器的优势。

要使用JavaScript 指定事件处理程序,首先必须取得一个要操作的对象的引用。

每个元素(包括window 和document)都有自己的事件处理程序属性,这些属性通常全部小写,例如onclick。将这种属性的值设置为一个函数,就可以指定事件处理程序,如下所示:

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

在此,我们通过文档对象取得了一个按钮的引用,然后为它指定了onclick 事件处理程序。

但要注意,在这些代码运行以前不会指定事件处理程序,因此如果这些代码在页面中位于按钮后面,就有可能在一段时间内怎么单击都没有反应。

使用DOM0 级方法指定的事件处理程序被认为是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行;换句话说,程序中的this 引用当前元素。来看一个例子。

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

单击按钮显示的是元素的ID,这个ID 是通过this.id 取得的。不仅仅是ID,实际上可以在事件处理程序中通过this 访问元素的任何属性和方法。以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。
也可以删除通过DOM0 级方法指定的事件处理程序,只要像下面这样将事件处理程序属性的值设置为null 即可:

btn.onclick = null; //删除事件处理程序
将事件处理程序设置为null 之后,再单击按钮将不会有任何动作发生。

DOM2级事件处理程序

“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法,并且它们都接受3 个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。要在按钮上为click 事件添加事件处理程序,可以使用下列代码:

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

// this 指向的是元素本身

上面的代码为一个按钮添加了onclick 事件处理程序,而且该事件会在冒泡阶段被触发(因为最后一个参数是false)。与DOM0 级方法一样,这里添加的事件处理程序也是在其依附的元素的作用域中运行。使用DOM2 级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。来看下面的例子。

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

4)IE事件处理程序

IE 实现了与DOM 中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。由于IE8 及更早版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。
要使用attachEvent()为按钮添加一个事件处理程序,可以使用以下代码。

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

注意,attachEvent()的第一个参数是"onclick",而非DOM 的addEventListener()方法中的"click"。
在IE 中使用attachEvent()与使用DOM0 级方法的主要区别在于事件处理程序的作用域。在使用DOM0 级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此==this 等于window。==来看下面的例子。

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

在编写跨浏览器的代码时,牢记这一区别非常重要。
与addEventListener()类似,attachEvent()方法也可以用来为一个元素添加多个事件处理程序。来看下面的例子。

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

这里调用了两次attachEvent(),为同一个按钮添加了两个不同的事件处理程序。不过,与DOM方法不同的是,这些事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发。单击这个例子中的按钮,首先看到的是"Hello world!",然后才是"Clicked"。

使用attachEvent()添加的事件可以通过detachEvent()来移除,条件是必须提供相同的参数。与DOM 方法一样,这也意味着添加的匿名函数将不能被移除。不过,只要能够将对相同函数的引用传给detachEvent(),就可以移除相应的事件处理程序。例如:

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

btn.attachEvent("onclick", handler);
//这里省略了其他代码
btn.detachEvent("onclick", handler);

这个例子将保存在变量handler 中的函数作为事件处理程序。因此,后面的detachEvent()可以使用相同的函数来移除事件处理程序。
支持IE 事件处理程序的浏览器有IE 和Opera。

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

第一个要创建的方法是addHandler(),它的职责是视情况分别使用DOM0 级方法、DOM2 级方法或IE 方法来添加事件。这个方法属于一个名叫EventUtil 的对象,使用这个对象来处理浏览器间的差异。

addHandler()方法接受3 个参数:要操作的元素、事件名称和事件处理程序函数。

与addHandler()对应的方法是removeHandler(),

它也接受相同的参数。这个方法的职责是移除之前添加的事件处理程序——无论该事件处理程序是采取什么方式添加到元素中的,如果其他方法无效,默认采用DOM0 级方法。
EventUtil 的用法如下所示。

var EventUtil = {
      /*
       * 添加事件
       * @param: element 要操作的元素
       * @param: type 事件名称
       * @param: handler 事件处理程序函数
       */
      addHandler: function (element, type, handler) {
        if (element.addEventListener) {
          // DOM2 级事件处理程序
          element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
          // IE事件处理程序
          element.attachEvent("on" + type, handler);
        } else {
          element["on" + type] = handler;
        }
      },
      /*
       * 删除已添加事件
       * @param: element 要操作的元素
       * @param: type 事件名称
       * @param: handler 事件处理程序函数
       */
      removeHandler: function (element, type, handler) {
        if (element.removeEventListener) {
          // DOM2 级事件处理程序
          element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
          // IE事件处理程序
          element.detachEvent("on" + type, handler);
        } else {
          element["on" + type] = null;
        }
      }
    }

这两个方法首先都会检测传入的元素中是否存在DOM2 级方法。如果存在DOM2 级方法,则使用该方法:传入事件类型、事件处理程序函数和第三个参数false(表示冒泡阶段)。如果存在的是IE 的方法,则采取第二种方案。

注意,为了在IE8 及更早版本中运行,此时的事件类型必须加上"on"前缀。

最后一种可能就是使用DOM0 级方法(在现代浏览器中,应该不会执行这里的代码)。时,我们使用的是方括号语法来将属性名指定为事件处理程序,或者将属性设置为null。

var btn = document.getElementById("myBtn");
var handler = function(){
    alert("Clicked");
};
EventUtil.addHandler(btn, "click", handler);
//这里省略了其他代码
EventUtil.removeHandler(btn, "click", handler);

addHandler()和removeHandler()没有考虑到所有的浏览器问题,例如在IE 中的作用域问题。不过,使用它们添加和移除事件处理程序还是足够了。

此外还要注意,DOM0 级对每个事件只支持一个事件处理程序。

好在,只支持DOM0 级的浏览器已经没有那么多了,因此这对你而言应该不是什么问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值