事件event

来源:互联网 发布:cpu测试软件 linux 编辑:程序博客网 时间:2024/05/16 02:49

事件流描述的是从页面中接收事件的顺序。

 其中IE的事件流是事件冒泡流,而Netscape Communicator 的事件流是事件捕获流。

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

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


DOM事件流:事件捕获阶段→处于目标阶段→事件冒泡阶段

注意:在事件处理,“处于目标”阶段被看成冒泡阶段的一部分。

事件处理程序

一、HTML事件处理程序

如:

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

在这种情况下,事件处理程序中的代码在执行时,有权访问 全局作用域中的任何代码

注意:此处使用的是 onclick,即事件处理程序名称。在函数内部,this值等于事件的目标元素

这种方式的独到之处
1. 会创建一个封装着元素属性值的函数。函数中有一个局部变量event,也就是事件对象,不需要自己定义,可以直接访问。
2. 扩展作用域的方式。在这个函数内部,可以像访问局部变量一样访问document及该元素本身的成员。

<input type="button" value="Click Me" onclick="alert(value)"><!--弹出"Click Me"-->

这个函数使用with像下面这样扩展作用域:

function (){    with(document){        with(this){            //元素属性。        }    }}

如果当前元素是一个表单输入元素:

<form>    <input type="text" name="username" value=""/>    <input type="button" value="Echo Username" onclick="alert(username.value)" />    <!--输出输入框内容--></form>

这个函数像下面这样扩展作用域

function(){    with(document){        with(this.form){            with(this){                //元素属性值            }        }    }}

这种方式的缺点
1. 存在时差。用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件。解决方法:处理程序用try-catch封装着。 如下:

<input type="button" value="Click Me" onclick="try{showMessage();}catch(ex){}"/>
  1. 这样扩展事件处理程序的作用域会导致不同浏览器程序作用域不同
  2. HTML与JS耦合

二、DOM0级事件处理程序

如:

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

注意:此处使用的是 onclick,即事件处理程序名称。在函数内部,this值等于事件的目标元素

以这种方式添加的事件处理程序会在事件流的 冒泡阶段 被处理的。

这种方式的缺点:
不能为同一事件添加多个事件处理。


三、DOM2级事件处理程序

DOM2级事件定义了两个方法addEventListenerremoveEventListener.所有的DOM节点都包含这两个方法,并且它们都接收三个参数:要处理的 事件名、作为事件处理程序的函数,一个布尔值。这个布尔值若为 true ,则表示在 事件捕获阶段 调用事件处理程序,若为false,则表示在 事件冒泡阶段 调用时间处理程序。

如:

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

注意:此处使用的是 click,即事件的名称。在函数内部,this值等于事件的目标元素

通过addEventListener添加的事件处理程序,只能使用removeEventListener移除,而移除时,传入的参数均一样,这就意味着,通过addEventListener()添加的匿名函数 无法移除 ,若需移除,请将该函数改成命名函数。

大多数情况下,都是将实践处理程序添加到事件流的冒泡阶段

这种方式的优点:
可以添加多个事件处理程序,而且这些事件处理程序是 按照添加它们的顺序触发 的。


IE事件处理程序

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

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

注意:此处使用的是 onclick,即事件的名称。在函数内部,this值等于window

!!强烈注意:在IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域。在使用DOM0级方法的情况下,事件处理程序会在其所属元素的作用域内运行,因此this指向事件的目标元素;在使用attachEvent方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。

这种方式的优点:
可以添加多个事件处理程序,而且这些事件处理程序是 按照添加它们的顺序的反序触发的。

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

需要创建两个方法:
1. addHandler():接收3个参数:要操作的元素、事件名称、事件处理程序函数。
2. removeHandler():接受同样的参数

var EventUtil = {    addHandler : function(element,type,handler){      if(element.addEventListener)  {          element.addEventListener(type,handler,false); //DOM2级      } else if(element.attachEvent){          element.attachEvent('on' + type,handler); //IE      } else{          element['on' + type] = handler;      }    },    removeHandler : function(element,type,handler){        if(element.removeElementListener){            element.removeElementListener(type,handler,false);        } else if(element.detachEvent){            element.detachEvent('on' + type,handler);        } else {            element['on' + type] = null;        }    }}


事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包含导致事件的元素、事件的类型以及其他与特定事件相关的信息。

DOM中的事件对象

兼容DOM的浏览器将会一个event对象传入事件处理程序中,无论指定事件处理程序时使用什么方法(DOM0级或DOM2级)。

event对象包含与创建它的特定事件有关的属性和方法,触发的事件类型不同,可用的方法和属性也不一样,但都包括一下几个属性(只列出常用的几种,详细请查阅资料或参考《JavaScript高级程序设计》355-356页)。
- currentTarget : Element类型,其事件处理程序当前正在处理事件的那个元素。
- preventDefault() :Function类型,取消事件的默认行为,若cancelable为true,则可以使用这个方法。
- stopPropagation() : Function类型,取消事件的进一步捕获或冒泡,如果bubbles为true,则可以使用这种方法。
- target : Element类型,事件的目标

在事件处理程序内部,对象this始终等于currentTarget,而target则只包含事件的实际目标。

IE中的事件对象

IE中的event对象的访问方式取决于指定事件处理程序的方法(与访问DOM中的event不同)。
1. 在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。
如:

var btn = document.getElmentById('myBtn');btn.onclick = function(){    var event = window.event;    alert(event.type);  //"click"}
  1. 事件处理程序是用attachEvent添加的,那么就会有一个event对象作为参数被传入事件处理程序。
var btn = document.getElmentById('myBtn');btn.attachEvent("onclick",function(event){    alert(event.type);  //"click"});
  1. 如果通过HTML特性指定的事件处理程序,那么会有一个名为event的变量来访问event对象。
<input type="button" value="Click Me" onclick="alert(event.type)"/>

与DOM的event对象一样,这些属性的方法也会因为事件类型的不同而不同。但都包括一下几个属性(只列出常用的几种,详细请查阅资料或参考《JavaScript高级程序设计》359页)。
- cancelBubble : Boolean类型,默认值为false,但将其设为true就可以取消事件冒泡(与DOM中的stopPropagation()方法的作用相同)
- returnValue : Boolean类型。默认值为true,但将其设为false就可以取消事件的默认行为(与DOM中的preventDefault()方法的作用相同)
- srcElement : Element类型,事件的目标(与DOM中的target属性相同)

由于this不是始终等于事件目标,所以最好用event.srcElment比较保险

跨浏览器的事件对象

在跨浏览器的事件处理程序的基础上,加上下列代码

var EventUtil = {    getEvent : function(event){        return event ? event : window.event;    },    getTarget : function(event){        return event.target || event.srcElement;    },    preventDefault : function(event){        if(event.preventDefault){            event.preventDefault();        } else {            event.returnValue = false;        }    },    stopPropagation : function(event){        if(event.stopPropagation){            event.stopPropagation();        }else{            event.cancelBubble = true;        }    }}
0 0
原创粉丝点击