《JavaScript高级程序设计》学习笔记:JavaScript中的事件流和事件处理程序

JavaScript和HTML之间的交互是经过事件实现的。javascript

事件:文档或浏览器窗口中发生的一些特定的交互瞬间。java

能够使用侦听器(或处理程序来预订事件),以便事件发生时执行相应的代码。浏览器


1. 事件流

事件流:从页面中接收事件的顺序。函数

IE和Netscape开发团队提出了差很少是彻底相反的事件流的概念。this

  • IE: 事件冒泡流
  • Netscape: 事件捕获流

1.1 事件冒泡

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

1.2 事件捕获

事件捕获(event capturing):不太具体的节点应该更早接收到事件,最具体的节点应该最后接收到事件。对象

事件捕获的用意在于在事件到达预约目标以前捕获它。seo

1.3 DOM事件流

“DOM2级事件”规定的事件流包括三个阶段:事件

1. 事件捕获阶段
2. 处于目标阶段
3. 事件冒泡阶段

2. 事件处理程序

事件是用户或浏览器自身执行的某种动做。如:click,load,mouseover。
响应某个事件的函数称为事件处理程序(或事件侦听器)ip

2.1 HTML事件处理程序

某个元素支持的每种事件,均可以使用一个与相应事件处理程序同名的HTML特性来指定。

<input type="button" value="Clicke Me" onclick="alert('Clicked')" />

单击按钮,显示警告框。经过指定 onclick 特性并将一些JavaScript代码做为它的值来定义。

在HTML中定义的事件处理程序能够包含要执行的具体动做,也能够调用在页面其余地方定义的脚本。

<script type="text/javascript">
    function showMessage() {
        alert("Hello world");
    }
</script>
<input type="button" value="Clicke Me" onclick="showMessage()" />

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

缺点:

  1. 存在时差问题。用户在事件处理程序被解析以前就触发了事件。
  2. 扩展事件处理程序的做用域链在不一样的浏览器中会致使不一样结果。
  3. HTML和JavaScript代码紧密耦合。

2.2 DOM0 级事件处理程序

经过JavaScript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。

这种方法被称为事件处理程序赋值,出如今第四代 Web 浏览器中。

每一个元素(包括 window 和 document)都有本身的事件处理程序属性,属性一般所有小写,如 onclick。将这种属性的值设置为一个函数,就能够指定事件处理程序。

<input type="button" id="myBtn" value="Click Me" />
    
    <script type="text/javascript">
        var btn = document.getElementById("myBtn");
        btn.onclick = function() {
            alert("Clicked");
        }
    </script>

能够删除经过 DOM0 级方法指定的事件处理程序。

btn.onclick = null;    // 删除事件处理程序

2.3 DOM2 级事件处理程序

“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操做:

  • addEventListener()
  • removeEventListener()

全部 DOM 节点都包含这两个方法,它们接受3个参数:

  1. 要处理的事件名
  2. 做为事件处理程序的函数
  3. 一个布尔值:

    • true: 捕获阶段调用事件处理程序
    • false: 冒泡阶段调用

为一个按钮添加 onclick 事件处理程序:

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

使用 DOM2级方法添加事件处理程序的主要好处是能够添加多个事件处理程序。

用 addEventListener() 添加的事件处理程序只能使用 removeEventListener() 来移除,移除时传入的参数与添加时的参数相同。因此,用 addEventListener() 添加的匿名函数将没法移除。

大多数状况下,都是将事件处理程序添加到事件流的冒泡阶段,这样能够最大限度地兼容各类浏览器。

2.4 IE 事件处理程序

IE 实现了与 DOM 中相似的两个方法:

  • attachEvent()
  • detachEvent()

接受两个参数:事件处理程序名称、事件处理程序函数
经过这种方法添加的事件处理程序会被添加到冒泡阶段。

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

注意: attachEvent() 的第一个参数是“onclick”,而不是 addEventListener()方法中的“click"。

在IE中使用 attachEvent() 与使用 DOM0 级方法的主要区别在于事件处理程序的做用域。

  • DOM0 级方法:事件处理程序会在其所属元素的做用域内运行
  • attachEvent()方法:事件处理程序会在全局做用域内运行,this 等于 window。

2.5 跨浏览器的事件处理程序

建立一个方法 addHandler(),它属于名叫EventUtil的对象视状况分别使用 DOM0级方法、 DOM2级方法或IE方法来添加事件。

addHandler()方法接收3个参数:

  1. 要操做的元素
  2. 事件名称
  3. 事件处理程序函数

与其对应的方法是 removeHandler(),接收相同的参数。

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

这两个方法首先都会检测传入的元素中是否存在DOM2级方法。若是存在DOM2级方法,则使用该方法。若是存在的是IE的方法,则采起第二种方案。

像下面这样使用EventUtil对象:

var btn = document.getElementById("myBtn");
var handler = function() {
    alert("Clicked");
}
EventUtil.addHandler(btn, "click", handler);
EventUtil.removerHandler(btn, "click", handler);
相关文章
相关标签/搜索