JavaScript:事件处理程序_A_山水子农的博客-程序员秘密

技术标签: DOM级事件处理程序  HTML事件处理程序  事件捕获  JavaScript  事件冒泡  IE事件处理程序  

  JavaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。
一、事件流
  事件流描述的是从页面中接收事件的顺序,IE的事件流是事件冒泡流,而Netscape Communicator的事件流是事件捕获流。
1、事件冒泡

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

<html>
<head>
    <title>山水子农</title>
</head>
<body>
    <div>Click Me</div>
</body>
</html>
如果你单击了页面中的<div>元素,那么这个click事件会按照如下顺序传播:

div -> body -> html -> document
对于冒泡流的事件流机制,存在如下的兼容问题:
IE5.5及更早版本:           div -> body -> document
IE5.5之后到IE9之前:         div -> body -> html -> document
IE9、Firefox、Chrome和Safari:  div -> body -> html -> document -> window

<html>
<head>
<title>事件冒泡</title>
<meta charset="utf-8">
<body id='body'>
<div id="box">
   <input type="button" value="按钮" id="btn">
</div>
<script>
function bodyz(){
   alert('我是body');
}
function boxz(){
   alert('我是div');
}
function btnz(event){
   alert('我是input');
   //event.stopPropagation();阻止事件冒泡之后点击按钮就不会出现‘我是div’、‘我是body’
}
var body=document.getElementById('body');
var box=document.getElementById('box');
var btn=document.getElementById('btn');
box.addEventListener('click',boxz,false);
btn.addEventListener('click',btnz,false);
body.addEventListener('click',bodyz,false);
</script>
</body>
</head>
点击按钮会依次弹出:‘我是input’、‘我是div’、‘我是body’

2、事件捕获

  事件开始的时候由最不具体的节点接收,然后逐级向下传播到最具体的节点。事件捕获的用意在于在事件达到预定目标之前捕获它。以上面的实例来看,click事件的执行顺序为:document -> html -> body -> div

  虽然事件捕获是Netscape Communicator唯一支持的事件流模型,但IE9、Firefox、Chrome、Opera和Safari目前也都支持这种事件流模型。尽管“DOM2级事件”规范要求事件应该从document对象开始传播,但这些浏览器都是从window对象开始捕获事件的。

  由于老版本的浏览器不支持,因此很少有人使用事件捕获。我们也建议大家放心地使用事件冒泡,在有特殊需要时在使用事件捕获。

3、DOM事件流
  “DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供机会。然后实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。


二、事件处理程序

1、HTML事件处理程序

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script>
function showMessage(){
	alert("HTML 事件处理程序");
}
</script>
<title>HTML 事件处理程序</title>
</head>
<body>
<input type="button" value="Click Me1" οnclick="alert('HTML 事件处理程')"/>
<input type="button" value="Click Me2" οnclick="showMessage()"/>
</body>
</html>

   在HTML中指定事件处理程序有两个缺点:

  (1)、存在一个时差问题。因为用户可能会在HTML元素出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件。

  (2)、HTML与JavaScript代码紧密耦合。如果要更换事件处理程序,就要改动两个地方:HTML代码和JavaScript代码。而这正是许多开发人员放弃HTML事件处理程序,转而使用JavaScript指定事件处理程序的原因所在。


2、DOM0级事件处理程序

    通过JavaScript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。这种为事件处理程序赋值的方法是在第四代Web浏览器中出现的,而且至今仍然为所有现代浏览器所支持。原因一是简单,二是具有跨浏览器的优势。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DOM0级事件处理程序</title>
</head>
<body>
<input type="button" value="Click Me" id="myBtn"/>
<script>
var btn=document.getElementById("myBtn");
btn.οnclick=function(){
	alert("DOM0级事件处理程序");
	setTimeout(function(){
	    btn.οnclick=null;//删除事件处理程序
	    alert("删除事件处理程序");
    },200);
}
</script>
</body>
</html>
3、DOM2级事件处理程序
  “DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有的DOM节点中都包含这两个方法,并且它们都接受3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DOM2级事件处理程序</title>
</head>
<body>
<input type="button" value="Click Me" id="myBtn"/>
<script>
var btn=document.getElementById("myBtn");
btn.addEventListener("click",function(){//click不要on,三个参数。
	alert("DOM2级事件处理程序1");
},false);
btn.addEventListener("click",function(){
	alert("DOM2级事件处理程序2");
},false);
//先输出DOM2级事件处理程序1后DOM2级事件处理程序2
</script>
</body>
</html>
  DOM0和DOM2级事件处理程序都有一个共同的优点就是可以同时添加多个事件处理程序。使用removeEventListener()移除addEventListener()事件时,移除时传入的参数与添加处理程序时使用的参数相同。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DOM2级事件处理程序</title>
</head>
<body>
<input type="button" value="Click Me" id="myBtn"/>
<script>
var btn=document.getElementById("myBtn");
var handler=function(){
	alert("DOM2级事件处理程序");
	setTimeout(function(){
	    btn.removeEventListener("click",handler,false);
	    alert("删除事件处理程序");
   },1000);
};
btn.addEventListener("click",handler,false);
</script>
</body>
</html>

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


4、IE事件处理程序
  IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>IE事件处理程序</title>
</head>
<body>
<input type="button" value="Click Me" id="myBtn"/>
<script>
var btn=document.getElementById("myBtn");
btn.attachEvent("onclick",function(){//click要加on,两个参数。
	alert("IE事件处理程序1");
});
btn.attachEvent("onclick",function(){
	alert("IE事件处理程序2");
});
//先输出IE事件处理程序2后IE事件处理程序1.
</script>
</body>
</html>
  使用detachEvent()移除attachEvent()事件时,移除时传入的参数与添加处理程序时使用的参数相同。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>IE事件处理程序</title>
</head>
<body>
<input type="button" value="Click Me" id="myBtn"/>
<script>
var btn=document.getElementById("myBtn");
var handler=function(){
	alert("IE事件处理程序");
	setTimeout(function(){
	    btn.detachEvent("onclick",handler);
	    alert("删除事件处理程序");
   },1000);
};
btn.attachEvent("onclick",handler);
</script>
</body>
</html>


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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>跨浏览器的事件处理程序</title>
</head>
<body>
<input type="button" value="Click Me" id="myBtn"/>
<script>
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{
		   element["on"+type]=handler;//DOM0级 <span style="font-family: Arial, Helvetica, sans-serif;">element[onclick]</span><span style="font-family: Arial, Helvetica, sans-serif;"> ===element.onclick</span>
	   }
   },//此处的","千万别忘记,EventUtil是对象。
   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;//DOM0级
	   }      
   }
}
var btn=document.getElementById("myBtn");
var handler=function(){
	alert("跨浏览器的事件处理程序");
	setTimeout(function(){
	    EventUtil.removeHandler(btn,"click",handler);
	    alert("删除事件处理程序");
   },1000);
};
EventUtil.addHandler(btn,"click",handler);//事件类型不要加"on"
</script>
</body>
</html>


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_27626333/article/details/51584919

智能推荐

windows删除“找不到该项目”的文件_magi617的博客-程序员秘密

1、编写一个自动删除脚本,内容如下:右键,新建文本文件重命名为del.bat编辑内容:del /F /A /Q \?\%1(第一行)rd /S /Q \?\%1(第二行)2、把要删除的文件直接拖到该脚本上即可删除3、原理方法采纳自百度经验删除文件时提示“找不到该项目”,怎么解决?del为windows删除文件的命令,rd为windows删除目录的命令,/F为强制删除参数,/A为根据文件

BeanUtils.copyProperties 如果Integer 或Long 为null 默认赋值0_空白-键的博客-程序员秘密

转自:http://nassir.iteye.com/blog/1585692BeanUtils.copyProperties(A,B);如果B中的Integer类型的数据是null的,那么通过这个方法复制给A后,这个null的Integer数据会变成0。也就是它有自己的规则,如果发现Integer类型的数据如果是null的,它会自作多情的给个默认值!这个自作多

阿里巴巴 数据分析师 2018.3笔试汇总_阿里巴巴数据分析师初级考试_Sisyphus.的博客-程序员秘密

是的,我又去笔试了,虽然被完虐,但是起码可以知道自己想要从事这一行业,应该要学些什么了。首先,概率论的题占大部分。这部分比较考验人的数学功底,和逻辑能力。其次,就是是数据库了,一道简答题,问题是比较简单的SQL语句。最后就是数据敏感性了。这个比较抽象。话不多说,上真题。首先是选择题:1.每一下午7点钟在10min内打到车的概率是90%,问,一周内至少两天打不到车的概率。2.有20个同学参加面试,其...

市场营销学9——产品策略_产品策略定义_长烟慢慢的博客-程序员秘密

1、什么是产品策略产品策略是市场营销4P组合的核心,是价格策略、分销策略和促销策略的基础。从社会经济发展看,产品的交换是社会分工的必要前提,企业生产与社会需要的统一是通过产品来实现的,企业与市场的关系也主要是通过产品或服务来联系的,从企业内部而言,产品是企业生产活动的中心。因此,产品策略是企业市场营销活动的支柱和基石。  产品策略是指企业制定经营战略时,首先要明确企业能提供什么样的产品

MAR与MDR是什么?_mar和mdr_自由的犇儿哥的博客-程序员秘密

Baby StepsWe’re going to take the first step in “building” the CPU. We’re going to introduce two registers: the MAR and the MDR. We assume both are 32-bit parallel load registers.MARMAR is short for memory address register. This register has its output

随便推点

cookie 实现记住用户名演示 通过代码迅速理解cookie_Sunnyqiong1117的博客-程序员秘密

// 登录页 可直接 tomcat部署 测试 1 package com.itheima.login; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 6 import javax.servlet.ServletException; 7 import javax.serv...

【丁雪丰(译)】SpringBoot实战第五节:Groovy与SpringBoot CLI《读后感》_丁雪丰 博客_总是幸福的老豌豆的博客-程序员秘密

前言本章主要为我们讲解:自动依赖与import获取依赖测试基于CLI的应用程序当看到标题时我是一愣,因为我接触springboot项目时,直接撸的代码,从来没有细致的去探究springboot的社区,我也不知道SpringBootCLI是个啥东东,阅读完章回头开始写本篇读后感后,我想说的是:我们越是学习,越觉得自己的贫乏,通过书中讲解我了解了SpringBootCLI是一个命令行工具,...

Strus 2的新表单标志的使用_iteye_813的博客-程序员秘密

Struts 2为大家提供了不少常用的很酷的表单标志,简化了我们程序员的工作。不过,由于这些都是新标志,大家可能在使用上还存在不少疑问。本文将就朋友们的回复、留言或Email上的问题,分别对这些酷标志进行讲述。表单标志使用小技巧Struts 2的表单标志在输出(render)HTML时,使用了模板的概念,增加了复杂性(因为它不像Struts 1.x的表单标志,它通常都是一个标志对应HTML的一...

关于内存对齐_weixin_34233856的博客-程序员秘密

内存地址对齐,是一种在计算机内存中排列数据(表现为变量的地址)、访问数据(表现为CPU读取数据)的一种方式,包含了两种相互独立又相互关联的部分:基本数据对齐和结构体数据对齐 。 为什么需要内存对齐?对齐有什么好处?是我们程序员来手动做内存对齐呢?还是编译器在进行自动优化的时候完成这项工作? 在现代计算机体系中,每次读写内存中数据,都是按字(word,4个字节,对于X86架构...

excel怎么把x坐标变成指定时间/日期_散点图如何让纵坐标变为月份_baowxz的博客-程序员秘密

1、处理数据时希望横轴为时间,Y轴时测到的数据2、比如有这列数据:希望作图时,x轴为时间这一列,其他列是实际测量值该怎么办呢3、excel处理步骤a)先作图b)选中图,右键点击选择数据,出现下图: 图中标明了,改的范围,点编辑即可选择X轴c)选择完成后,最终图表如下图:X轴已经变为时间了...

java面试题及答案(1)_小哥、的博客-程序员秘密

JAVA相关基础知识1、面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。2.继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的

推荐文章

热门文章

相关标签