1、事件流

事件冒泡

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

事件捕获

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

DOM事件流

“DOM2级事件流”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件作出响应。以简单的HTML页面为例,单击<div>元素会按照下图顺序触发事件

在DOM事件流中,实际的目标(<div>元素)在捕获阶段不会接收到事件。这意味着在捕获阶段,事件从document到<html>再到<body>后就停止了。下一个阶段是“处于目标”阶段,于是事件在<div>上发生,并在事件处理中被看成冒泡阶段的一部分。然后冒泡阶段发生,事件又传播回文档。

多数支持DOM事件流的浏览器都实现了一种特定行为;即使“DOM2级事件”规范明确要求捕获阶段不会涉及事件的目标,但Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两个机会在目标对象上面操作事件。

Opera、Firefox、Chrome和Safari都支持DOM事件流;IE不支持DOM事件流。

2、事件处理程序(或事件侦听器)

事件是用户或浏览器自身执行的某种动作。诸如click、load和mouseover,都是事件的名字。 而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。事件处理程序的名字以“on”开头,因此click事件的事件处理程序就是onclick等。为事件指定处理程序的方式有好几种。

HTML事件处理程序

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

<input type="button" value="Click me"  onclick="alert('Clicked')"/>
<script type="text/javascript">
function showMessage(){
alert("Hello World!");
}
</script>
<input type="button" value="Click me" onclick="showMessage()"/>

在HTML中指定事件有两个缺点。首先,存在一个时差问题。因为用户可能在HTML元素一出现在页面上就触发相应的事件,但当时事件处理程序有可能尚不具备执行条件。例如前面的例子,假设showMessage函数在按钮下方页面最底部定义的,如果用户在页面解析showMessage函数之前就单击了按钮,就会引发报错。第二个确定是HTML与JavaScript代码紧密耦合。如果要更换事件处理程序,就要改动两个地方。

DOM0级事件处理程序

通过JavaScript指定事件处理程序的传统方式,就是讲一个函数赋值给一个事件处理程序属性。要使用JavaScript指定事件处理程序,首先必须取得一个要操作的对象的引用。

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

使用DOM0级方法指定的事件处理程序被认为是元素的方法,因此是在元素的作用域中运行,换句话说,程序中的this引用当前元素。

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

可以在事件处理程序中通过this访问元素的任何属性和方法,以这种方式添加的事件处理程序会在事件流中的冒泡阶段被处理。

可以删除通过DOM0级方法指定的事件处理程序,只要将事件处理程序属性的值设为null即可。

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

DOM2级事件处理程序

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

与DOM0级方法一样,DOM2级方法天际的事件处理程序也是在其依附的元素的作用域中进行。使用DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。来看下面的例子:

btn.addEventListener("click",function(){
alert(this.id);
},false);
btn.addEventListener("click",function(){
alert("Hello World!");
},false);

这里为按钮多添加了两个事件处理程序。这两个事件处理程序会按照添加它们的顺序触发,因此首先会显示元素ID,其次会显示“Hello World!”消息。

通过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); //有效!

大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种浏览器。最好只在需要事件到达目标之前截获它的时候将事件处理程序添加到捕获阶段。如果不是特别需要,我们不建议在事件捕获阶段注册事件处理程序。

Firefox、Safari、Chrome和Opera支持DOM2级事件处理程序

IE事件处理程序

IE实现了与DOM类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。由于IE只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

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

注意:第一个参数为“onclick”,而非DOM的addEventListener()方法中的"click"。

在IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域。DOM0级事件处理程序会在其所属元素的作用域内运行;在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。在编写跨浏览器的代码时,牢记这一点区别非常重要。

attachEvent()也可以为一个元素添加多个事件处理程序,来看下面的例子:

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

与DOM方法不同的是,这些事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发。单击这个例子中的按钮,首先看到的是“Hello World!”,然后才是“Clicked”。

使用attachEvent()添加的事件可以通过detachEvent()来移除,条件是必须提供相同的参数。与DOM方法一样,添加的匿名函数将不能被移除。

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

js事件流、事件处理程序/事件侦听器的更多相关文章

  1. 异常将上下文初始化事件发送到类的侦听器实例.[org.springframework.web.context.ContextLoaderListener] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class p

    严重: 异常将上下文初始化事件发送到类的侦听器实例.[org.springframework.web.context.ContextLoaderListener]org.springframework ...

  2. Vue.js之Vue计算属性、侦听器、样式绑定

    前言 上一篇介绍了Vue的基本概念,这一篇介绍一下Vue的基本使用. 一.搭建一个Vue程序 1.1 搭建Vue环境 搭建Vue的开发环境总共有三种方法: 引入CDN <script src=& ...

  3. JavaScript DOM高级程序设计 4.3控制事件流和注册事件侦听器--我要坚持到底!

    一.事件流 我们通过下面一个实例,进行说明. <body> <h1>Event Flow</h1> <ul id="nav"> &l ...

  4. javascript中事件总结&通用的事件侦听器函数封装&事件委托

    前言: JAVASCRIPT与HTML之间的交互是通过事件来实现的.事件,就是文档或浏览器窗口中发生的一些特定交互瞬间.可以使用侦听器( 或处理程序 )来预定事件,以便事件发生时执行相应的代码.这种在 ...

  5. Android事件侦听器回调方法浅谈

    http://developer.51cto.com/art/201001/180846.htm Android事件侦听器作为视图View类的接口,其中包含有不少回调方法,比如:onClick():o ...

  6. 052_末晨曦Vue技术_处理边界情况之程序化的事件侦听器

    程序化的事件侦听器 点击打开视频讲解更详细 现在,你已经知道了 $emit 的用法,它可以被 v-on 侦听,但是 Vue 实例同时在其事件接口中提供了其它的方法.我们可以: 通过 $on(event ...

  7. DOM事件: DOM事件级别、DOM事件流、DOM事件模型、DOM事件捕获过程、自定义事件

    前端面试中只要问到事件,就肯定会有DOM事件:如果回答出来了,就会一直向下延申,其实这些东西都很简单,但我第一次被问到的时候,也是懵的: DOM事件级别: DOM0 element.onclick = ...

  8. IE和DOM事件流、普通事件和绑定事件的区别

    IE和DOM事件流的区别 IE采用冒泡型事件 Netscape(网络信息浏览器)使用捕获型事件 DOM使用先捕获后冒泡型事件 示例: <body> <div> <butt ...

  9. Vue.js 生命周期、计算属性及侦听器

    一.创建一个Vue实例 每个Vue应用都是使用Vue函数创建一个Vue实例.所有的Vue组件都是一个Vue实例,并且接受相同的选项对象(一些根实例特有的选项除外). 数据和方法 当一个实例被创建后,它 ...

随机推荐

  1. PHP基本语法(一)

    整形:就是对用整数  正整数与负整数整形的表示:int integer NOTICE:写整形的时候不要在外面再加引号了 浮点:就是小数 3.1415926Float 浮点 布尔值:男和女 真和假 阴和 ...

  2. Log4E

    工具地址:http://marketplace.eclipse.org/content/log4e Log4E插件能够帮助你在Java项目中轻松地创建记录器.它可以在以下几个任务中提供帮助:记录器声明 ...

  3. ubuntu14.04中安装QuartusII9.1步骤

    家里的计算机安装了WIN10,出于够用且安装文件小,想安装QuartusII9.1,按M$风格,驱动绝对是安不上的.正好是双系统ubuntu14.04 64位.安装过程不太顺利,记录下来,当作已经不灵 ...

  4. index of rmvb mp3 rm突破站点入口下载

    首先打开Google,在关键词输入框中输入"index of/"inurl:lib(双引號为英文状态下) ,选择“搜索中文简体网页”选项,回车搜索,得到了一些网页,不要以为这是一些 ...

  5. netbeans下将全部jar包打成一个,俗称fat jar

    netbeans的java项目中.默认会将配置好的外部引用jar包,复制到dist文件夹的lib文件夹中去.假设须要公布出去.就须要将dist文件夹生成的jar和lib文件夹都拷贝出去公布,不方便. ...

  6. java10 WeakHashMap

    WeakHashMap: 对象所占用的区域是不能直接操作的,都是通过引用来操作. 引用分类: .强引用(StrongReference):gc(垃圾回收机制)运行时不回收.例如字符串常量池.字符串虽然 ...

  7. Linux系统及应用问题分析排查工具

    linux 阿里技术协会 摘要: Linux服务器上经常遇到一些系统和应用上的问题,如何分析排查,需要利器,下面总结列表了一些常用工具.trace tool:最后也列举了最近hadoop社区在开发发展 ...

  8. Memcached原理

    Memcached是一套高性能的.分布式内存对象缓存系统.它由C写成,以Key/Value的方式将数据储存在内存中. 一.Memcached特性 Memcached作为高速运行的分布式缓存服务器,具有 ...

  9. js基础1

    一.JavaScript 不同于Java 有三部分组成 核心(ECMAScript) 文档对象模型(DOM) 浏览器对象模型(BOM) 二.var 是定义数据前加的前缀   三.弹出 alert( ) ...

  10. 黑色遮罩引导蒙版 CSS实现方式

    一.微云的实现 网站有一些改动的时候,为了让用户熟知新的操作位置,往往会增加一个引导,常见的方式就是使用一个黑色的半透明蒙版,然后需要关注的区域是镂空的. 然后上周五我去微云转悠的时候,也看到了引导层 ...