JavaScript:事件流与事件处理程序

版权声明:此文章转载自极客头条

如需转载请联系听云College团队成员小尹 邮箱:yinhy#tingyun.com

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

事件流

事件流:描述的是从页面中接收事件的顺序。IE和Netscape提出了完全相反的事件流的概念。IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流。

事件冒泡

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

以下面的HTML页面为例:

<!DOCTYPE html>
<html>
<head>
    <title>事件冒泡</title>
</head>
<body>
    <div id="myDiv">Click Me</div>
</body>
</html>

事件冒泡过程:

2.png

事件捕获

Netscape提出的另一种事件流称为事件捕获。即不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。

事件捕获的过程:

3.png


DOM事件流

“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡。

4.png


事件处理程序

事件处理程序(事件侦听器):响应某个事件的函数。事件处理程序的名字以“on”开头,因此click事件的事件处理程序就是onclick,load事件的时间处理程序就是onload。

HTML事件处理程序

某个元素支持的每种事件,都可以使用一种响应事件处理程序同名的HTML特性来指定。这个特性的值应该是能够执行的JavaScript代码。

<input type="button" value="click me" onclick="alert('点击')">
// 使用双引号
<input type="button" value="click me" onclick="alert(&quot;点击&quot;)">
在HTML中定义的事件处理程序可以包含要执行的具体动作,也可以是调用在页面其他地方定义的脚本:
<script type="text/javascript">
    function showMsg() {
        alert("hello javascript");
    }
</script>
<input type="button" value="点击" onclick="showMsg();">

单击按钮就会调用showMsg()函数。事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码。

DOM0级事件处理程序

每个元素都有自己的事件处理程序属性,将这种属性的值设置为一个函数,就可以指定时间处理程序:

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

删除通过DOM0级方法指定的事件处理程序

btn.onclick = null;

DOM2级事件处理程序

“DOM2级事件”定义两个方法:addEventListener()和removeEventListener()。

所有DOM节点都包含着两个方法,并且它们都接受3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。布尔值参数为true,表示在捕获阶段调用事件处理程序;为false,表示在冒泡阶段调用事件处理程序。

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

使用DOM2级方法添加事件处理程序的好处是可以添加多个事件处理程序。

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

通过addEventListener()添加的事件处理程序只能使用removeEventListener()移除,移除时使用的参数与添加时使用的参数相同。这意味着addEventListener添加的匿名函数无法移除。

var btn = document.getElementById("myBtn");
btn.addEventListener("click", function () {
    alert(this.id);
}, false);
// 执行其他任务
btn.removeEventListener("click", function () {
    alert(this.id);
}, false);  // 无效

移除事件处理方法:

var btn = document.getElementById("myBtn");
var handler = function() {
    alert(this.id);
};
btn.addEventListener("click", handler, false);
// 执行其他任务
btn.removeEventListener("click", handler, false);

IE事件处理程序

IE中有两个与DOM类似的方法:attachEvent()和detachEvent()。

添加事件处理程序:

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

与DOM0级方法的区别:DOM0级方法下,事件处理程序与其所属元素的作用域内运行;在使用attachEvent()方法下,事件处理程序会在全局作用域中运行,因此this等于window。

移除事件处理程序:

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

跨浏览器的事件处理程序

var EventUtil = {
    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 {    // DOM0级
            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;
        }
    }
};

上面的EventUtil用于处理浏览器之间的差异。

EventUtil的使用:

var btn = document.getElementById("myBtn");
var handler = function () {
    alert("Clicked");
};
EventUtil.addHandler(btn, "click", handler);
// do something
EventUtil.removeHandler(btn, "click", handler);

1.png

想阅读更多技术文章,请访问听云技术博客,访问听云官方网站感受更多应用性能优化魔力。

关于作者

郝淼emily

重新开始,从心开始

我要评论

评论请先登录,或注册