首页 > 网站 > WEB开发 > 正文

史上最详细的JavaScript事件使用指南

2024-04-27 14:08:56
字体:
来源:转载
供稿:网友

史上最详细的javaScript事件使用指南

事件流

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

 事件冒泡

  IE的事件流叫做事件冒泡,即事件开始时由最具体的元素(文档中嵌套最深的那个节点)接收,然后逐级向上(一直到文档);如下代码:

<div id = "div">    <span id="span">        <a id="aTag">事件测试</a>    </span></div>

  JS如下:

document.getElementById("aTag").addEventListener('click',aTag);document.getElementById("span").addEventListener('click',span);document.getElementById("div").addEventListener('click',div);function aTag(e) {    alert("点击的是a标签");}function span(e) {    alert("点击的是span标签");}function div(e) {    alert("点击的是div标签");}

  当单击 “事件测试”文字后,那么click事件会按照如下顺序传播;

  1)先打印出:点击的是a标签

  2) 再打印出:点击的是span标签

  3) 最后打印出:点击的是div标签

  4) 最后肯定是document文档。

  所有现代浏览器都支持事件冒泡。

 事件捕获:

  事件捕获与事件冒泡事件流正好相反的顺序,事件捕获的事件流是最外层逐级向内传播,也就是先document,然后逐级div标签 ,span标签 , a标签;

  上面的JS代码改成如下:

document.getElementById("div").addEventListener('click',div,true);document.getElementById("aTag").addEventListener('click',aTag,true);document.getElementById("span").addEventListener('click',span,true);

  第三个参数设置为true,即为捕获事件,默认为false;否则的话,事件流还是和上面的一样,因为不管是在IE还是标准浏览器下,事件冒泡浏览器都支持的。

 DOM事件流

  DOM2级事件规定的事件流包括三个阶段,分别是:事件捕获阶段,处于目标阶段和事件冒泡阶段。示意图就不画了,具体的可以看看书。

 DOM0级事件处理程序

  如下代码是DOM0级事件处理程序:

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

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

<div id="btn">btn</div>var btn = document.getElementById("btn");btn.onclick = function(){    alert(this.id); // 弹出btn}

  单击元素btn后,通过this.id取得元素的属性id,还可以通过this访问元素的任何属性和方法,以这种方式添加的事情处理程序在事件流的冒泡阶段处理。

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

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

  如下JS代码改成如下:

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

  再单击btn后,没有任何反应;

 DOM2级事件处理程序

  DOM2级事件定义了2个方法,用于处理指定和删除事件处理程序的操作;

  addEventListener()和removeEventListener()。所有DOM节点都包含这两个方法,他们包含三个参数,第一个参数为事件类型;第二个参数为事件函数,第三个参数为布尔值,如果是true的话,说明是事件流是捕获事件,如果是false的话,那么事件流是冒泡事件;

  比如如上的btn代码,我们改成如下:

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

  上面的点击事件是在冒泡阶段被触发,与DOM0级方法一样,这里添加的事件处理程序也是在其依副的元素作用域中运行,使用DOM2级添加事件处理程序的好处是可以添加多个事件处理程序,如下代码:

var btn = document.getElementById("btn");btn.addEventListener('click',function(e){    alert(this.id);},false);btn.addEventListener('click',function(e){    alert("我是来测试的");},false);

  上面的代码被弹出2次对话框,而在DOM0级是不可以的;它永远是执行最后一次的。

  addEventListener添加的事件只能使用removeEventListener来删除相对应的事件,那么如上的JS不能按照上面的方式来编写哦!需要给定义一个函数;如下:

btn.addEventListener('click',handler,false);function handler(e){   alert(this.id);}

  可以使用如下方式对click事件删除;如下代码:

  btn.removeEventListener(‘click’,handler);

  上面的是在标准浏览器下处理的事件,下面我们来看看在IE下处理的事件;

 IE事件处理的程序

  IE实现了与DOM类似的2个方法,分别是attachEvent()和detachEvent(),这两个方法只接受2个参数,第一个参数是事件名称,第二个参数是要处理的函数;由于IE8及更早版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序会被添加到冒泡阶段;

  下面是IE事件处理程序的代码如下:

btn.attachEvent('onclick',handler);function handler(e){    alert(this); // window}

  注意:attachEvent的事件名称是onclick,而addEventListener的事件名称是click,且IE中使用的attachEvent()与使用DOM0级方法的的主要区别在于事件处理程序的作用域,在使用dom0级情况下,事件处理程序在其所属元素的作用域内运行,在使用attachEvent()方法的情况下,事件处理程序在全局作用域下运行,其中的this等于window。

  与addEventListener一样,attachEvent也可以注册多个点击click事件,如下代码:

btn.attachEvent('onclick',function(e){    alert("1");});btn.attachEvent('onclick',function(e){    alert("2");});

  但是与Dom方法不同的是,这些事件处理程序不是以添加他们的顺序执行,而是以相反的顺序触发,比如如上代码,会先弹出2,然后弹出1对话框;

  使用attachEvent注册的事件只能使用detachEvent()方法来移除;

  下面我们可以来编写跨浏览器的事件处理程序;代码如下:

var EventUtil = {    addHandler: function(element,type,handler) {        if(element.addEventListener) {                        element.addEventListener(type,handler,false);        }else if(element.attachEvent) {                    element.attachEvent("on"+type,handler);        }else {            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;        }    }};

  下面我们可以使用这个封装的函数代码来测试之前的代码了,代码改成如下所示:

function handler(){    alert(1);}EventUtil.addHandler(btn,'click',handler);

  在IE或者标准浏览器下都会弹出1;如果我们需要移除click事件的话,我们可以使用如下代码:

  EventUtil.removeHandler(btn,’click’,handler);

  然后在标准浏览器下或者IE下点击btn元素都没有反应;

 事件对象:

  在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息;包括导致事件的元素,事件的类型以及其他与特定事件相关的信息。我们来看看dom0级和dom2级的事件对象Event;

  比如如下代码:

var btn = document.getElementById("btn");btn.onclick = function(e){    console.log(e);}

  打印如下:

  下面我们来看看最基本的成员的含义吧;如下:

属性/方法类型含义
bubblesBoolean事件是否冒泡
cancelableBoolean是否可以取消事件的默认行为
currentTargetBoolean事件处理程序当前正在处理事件的那个元素
defaultPReventedBoolean为true 表示已经调用了preventDefault()
detailInteger与事件相关的细节信息
eventPhaseInteger调用事件处理程序的阶段:1表示捕获阶段,2表示“处于目标”,3表示冒泡阶段
preventDefault()Function取消事件的默认行为。如果cancelable是true,则可以使用这个方法
stopImmediatePropagation()Function取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用
stopPropagation()Function取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法
targetElement事件的目标
typeString被触发的事件的类型
viewAbstractView与事件关联的抽象视图。等同于发生事件的window对象

 理解currentTarget与target

  在事件处理程序内部,this始终等于currentTarget值,即currentTarget是指当前被触发或者说正在处理事件的那个元素,而target是指当前的目标元素;比如如下代码,对btn按钮触发点击事件,那么e.currentTraget指向了this,e.target也指向了this;如下代码:

var btn = document.getEleme
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表