关于JavaScript 的事件综合分析

  A 事件流(event flow )

  事件模型分为两种:冒泡型事件、捕获型事件。

  冒泡型(dubbed bubbling )事件:指事件按照从最精确的对象到最不精确的对象的顺序逐一触发。

  捕获型(event capturing )事件:它与冒泡型事件相反,指事件按照从最不精确的对象到最精确的对象的顺序逐一触发。

关于JavaScript 的事件综合分析

  捕获型事件也被称作自顶向下(DOM层次)的事件模型。

  由于IE 浏览器不支持捕获型事件,因此并没有被广泛应用。

  B 事件监听

  i > 通用监听方法

  示例一:

  

复制代码 代码如下:

  <p onclick="alert('点击了');">Click Me</p>

  示例二:

  

复制代码 代码如下:

  <html>

  <head>

  <title> demo </title>

  <meta name="Author" content="xugang" />

  <script type="text/javascript">

  // 在onload 事件中添加所有标签的事件

  window.onload = function(){

  // 找到对象

  var o_p = document.getElementById("myp");

  // 添加对象的onclick 事件

  o_p.onclick = function(){

  alert("我被点击了");

  }

  }

  </script>

  </head>

  <body>

  <p id="myp">Click Me</p>

  </body>

  </html>

  此代码实现了结构与行为的分离。

  给浏览器添加监听方法,分为两种:IE 中的监听方法、标准DOM 的监听方法。

  ii > IE 中的监听方法

  在IE 浏览器中,每个元素都有两个方法来处理事件的监听。分别是:attachEvent( ) 和 detachEvent( ) 。

  附加事件方法:[object].attachEvent(“事件名”,方法名);

  分离事件方法:[object].detachEvent(“事件名”,方法名);

  如:o_p.detachEvent("onclick",click_A);

  示例:

  

复制代码 代码如下:

  <html>

  <head>

  <title> demo </title>

  <meta name="Author" content="xugang" />

  <script type="text/javascript">

  <!--

  function click_A(){

  alert("click_A");

  //删除监听函数

  o_p.detachEvent("onclick",click_B);

  }

  function click_B(){

  alert("click_B, 我只调用一次。");

  }

  var o_p;

  window.onload = function(){

  o_p = document.getElementById("myP");

  // 添加监听函数 click_A

  o_p.attachEvent("onclick",click_A);

  // 添加监听函数 click_B

  o_p.attachEvent("onclick",click_B);

  }

  //-->

  </script>

  </head>

  <body>

  <p id="myP">Click Me</p>

  </body>

  </html>

  注意:

  ● 使用这种方式可以为同一元素添加多个监听函数;

  ● 在IE 浏览器中,函数的执行顺序与函数的添加顺序相反;

  ● 在IE 浏览器中,虽然函数有先后执行顺序,但都会同时调用;

  iii > 标准DOM 的监听方法

  在使用标准DOM 的浏览器中,每个元素也有两个方法来处理事件的监听。分别是:addEventListener( ) 和 removeEventListener( ) 。

  添加事件监听方法:[object].addEventListener(“事件名”,方法名,事件模型 );

  移除事件监听方法:[object].removeEventListener(“事件名”,方法名,事件模型 );

  注意:

  这里的“事件名”不能带 on ,如:click(如果是onclick 则错误!)

  “事件模型”为boolean 类型,通常设置为 false ,即“冒泡型”事件。(如果是true 则为“捕获型”事件)

  示例:

  

复制代码 代码如下:

  <html>

  <head>

  <title> demo </title>

  <meta name="Author" content="xugang" />

  <script type="text/javascript">

  <!--

  function click_A(){

  alert("click_A");

  //删除监听函数

  o_p.removeEventListener("click",click_B,false);

  }

  function click_B(){

  alert("被click_A删除, 一次都不能调用。");

  }

  var o_p;

  window.onload = function(){

  o_p = document.getElementById("myP");

  // 添加监听函数 click_A

  o_p.addEventListener("click",click_A,false);

  // 添加监听函数 click_B

  o_p.addEventListener("click",click_B,false);

  }

  //-->

  </script>

  </head>

  <body>

  <p id="myP">Click Me</p>

  </body>

  </html>

  在Firefox 下运行通过,在IE 下报错。

  注意:

  ● 使用这种方式同样可以为同一元素添加多个监听函数;

  ● 在Firefox 浏览器中,函数的执行顺序与函数的添加顺序一致(Firefox 与IE 正好相反);

  ● 在Firefox 浏览器中,这种方式添加的函数是执行外一个再执行另一个(逐个执行);

  C 事件对象

  i > 在IE 浏览器中,事件对象是window 对象的一个属性event 。访问方式如下:

  

复制代码 代码如下:

  function getEvent(){

  var o_event = window.event;

  }

  event 对象在事件发生时被访问,执行完函数后就消失了。

  ii > 在标准的DOM 中,事件对象是作为处理函数的唯一参数来获得。访问方式如下:

  

复制代码 代码如下:

  function getEvent(_event){

  var o_event = _event

  }

  因此,为了兼容各种浏览器,通常采用如下方法:

  

复制代码 代码如下:

  function getEvent(_event){

  // Firefox下参数_event 就是event对象

  // IE 下获得 event对象

  if(window.event)_event = window.event;

  // 显示触发的事件名称

  alert(_event.type);

  }

  

  下面列出了事件常用的几个属性和方法(区别):

IE 标准DOM 说明
cancelBubble cancelBubble 是否冒泡(标准DOM中只读)
stopPropagation( ) 阻止事件向上冒泡的方法
charCode 按下按键的Unicode 值
keyCode keyCode IE 中keypress 事件时表示按键的Unicode 值;

  标准DOM 中keypress 事件时为0;

  其余情况下,keyCode 为按键的数字代号。

srcElement target 触发事件的元素(对象源)
type type 事件的名称
此处只列出了事件成员的一小部分。

  注意:

  在IE 浏览器中,获得触发事件的对象源(HTML标签)是通过event 对象的srcElement 属性;

  在标准的DOM 中,获得触发事件的对象源(HTML标签)是通过event 对象的target 属性;

  获取事件目标的示例:

  

复制代码 代码如下:

  <html>

  <head>

  <title>事件的目标</title>

  <script language="javascript">

  function handle(oEvent){

  //处理兼容性,获得事件对象

  if(window.event) oEvent = window.event;

  var oTarget;

  //处理兼容性,获取事件目标

  if(oEvent.srcElement)

  oTarget = oEvent.srcElement;

  else oTarget = oEvent.target;

  //弹出目标的标记名称

  alert(oTarget.tagName);

  }

  window.onload = function(){

  var obj = document.getElementsByTagName("a")[0];

  obj.onclick = handle;

  }

  </script>

  </head>

  <body>

  <a href="#">获得事件源的示例</a>

  </body>

  </html>

  D 键盘事件

  

事件 说明
keydown 按下键盘上的某个键触发。(一直按住某键则会持续触发
keypress 按下某个按键并产生字符时触发。(即忽略Shift 、Alt 、Ctrl 等功能键
keyup 释放某个按键时触发。
触发的顺序为:keydown ---> keypress ---> keyup

  i > 关于keyCode属性和charCode 属性

  keyCode属性: 表示键盘按键码。因此输入“a”字母和“A”字母时,都是显示键盘码 65 ;

  charCode 属性:表示输入字符码。因此输入“a”字母和“A”字母时,

  分别显示 97(a 字符码)和 65(A 字符码);

  注意:

  在标准的DOM 中:既有keyCode属性,还有charCode 属性。

  但在标准的DOM 中,keypress 事件中keyCode 属性值始终为0 值;

  在IE 浏览器中:事件对象只有keyCode属性,没有charCode 属性。

  但在IE 浏览器中,keypress 事件中的keyCode 属性值等同于标准DOM 中的charCode 属性的值;

  示例代码:

  

复制代码 代码如下:

  <html>

  <head>

  <title>键盘事件</title>

  <script language="javascript">

  function handle(oEvent){

  if(window.event){

  //处理兼容性,获得事件对象

  oEvent = window.event;

  //设置IE的charCode值

  oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;

  }

  var oDiv = document.getElementById("display");

  //输出测试

  oDiv.innerHTML += oEvent.type // 事件名称

  + ": charCode:" + oEvent.charCode // 字符码 charCode

  + " keyCode:" + oEvent.keyCode + "<br>"; // 键盘码 keyCode

  }

  window.onload = function(){

  var oTextArea = document.getElementsByTagName("textarea")[0];

  oTextArea.onkeypress = handle;

  oTextArea.onkeydown = handle;

  }

  </script>

  </head>

  <body>

  <textarea rows="4" cols="50"></textarea>

  <div id="display"></div>

  </body>

  </html>

  ii > 屏蔽鼠标右键

  方法一:

  通过鼠标事件中,判断event 对象的button 属性值为“2”来屏蔽鼠标右键。虽然这种方法在IE 浏览器中有效,但在标准的DOM 中无效。并且,鼠标事件中,button 属性的值在IE 浏览器和标准的DOM 中大部分都不相同!

  方法二:

  其实,点击鼠标右键会触发右键菜单contextmenu 事件。

  所以,屏蔽鼠标右键最有效的办法就是屏蔽document 对象的contextmenu 事件。

  代码如下:

  

复制代码 代码如下:

  <html>

  <head>

  <title>屏蔽鼠标右键</title>

  <script language="javascript">

  function block(oEvent){

  if(window.event){

  oEvent = window.event;

  // IE 取消默认事件

  oEvent.returnValue = false;

  }

  else

  // Firefox 取消默认事件

  oEvent.preventDefault();

  }

  // 右键菜单事件

  document.oncontextmenu = block;

  </script>

  </head>

  <body>

  <p>屏蔽鼠标右键</p>

  </body>

  </html>

  IE 浏览器是通过returnValue 属性屏蔽右键菜单;

  标准DOM 是通过preventDefault( ) 方法屏蔽右键菜单;

  iii > 自定义鼠标右键菜单

  代码如下:

  

复制代码 代码如下:

  <html>

  <head>

  <title> demo </title>

  <meta name="Author" content="xugang" />

  <script type="text/javascript">

  <!--

  // 一、屏蔽系统右键菜单

  window.document.oncontextmenu = function(_event){

  if (window.event){

  _event = window.event;

  window.event.returnValue=false;

  window.event.cancelBubble=true;

  }

  else _event.preventDefault();

  }

  //二、添加自定义右键菜单

  window.document.onmouseup = function(_event)

  {

  var myDIV = document.getElementById("myDIV");

  // 浏览器兼容性

  if (window.event)_event = window.event;

  // 鼠标右键

  if(_event.button == 2)

  {

  // _event.clientX 获得鼠标当前的 X 坐标

  /* 注意:

  _event.clientX 的值在标准的DOM 中“只读”

  myDIV.style.pixelLeft 不是标准的DOM 属性

  */

  myDIV.style.left = _event.clientX;

  myDIV.style.top = _event.clientY;

  myDIV.style.display = "block";

  }

  // 不是鼠标右键

  else myDIV.style.display = "none";

  }

  //-->

  </script>

  </head>

  <body>

  <!-- 我的右键菜单 -->

  <div id="myDIV" style="position:absolute; height:180px; width:200px;

  background-color:#CCCCCC; display:none;">

  <a href="http://xugang.cnblogs.com" target="_blank">xugang</a>

  </div>

  </body>

  </html>

  在IE 浏览器和标准DOM 下兼容。