您的位置:首页 > Web前端 > JavaScript

轻松学习JavaScript二十七:DOM编程学习之事件模型

2015-12-28 20:50 555 查看
在介绍事件模型之前,我们先来看什么是事件和什么是event对象。

一事件介绍

JavaScript事件是由访问Web页面的用户引起的一系列操作,使我们有能力创建动态页面,事件是可以被

JavaScript侦测到的行为。网页中的每个元素都可以产生某些可以触发JavaScript函数的事件。比方说,我们可以在用

户点击某按钮时产生一个onclick事件来触发某个函数。事件在HTML页面中定义;事件通常与函数配合使用,当事件

发生时函数才会执行;事件一般用于浏览器和用户操作进行交互。

我们经常用到的事件举例:鼠标点击,页面或图像载入,鼠标悬浮于页面的某个热点之上,在表单中选取输入

框,确认表单,键盘按键等等。

二event对象

Event对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。事

件通常与函数结合使用,函数不会在事件发生前被执行!

当触发某个事件时,会产生一个事件对象,这个对象包含着所有与事件有关的信息,包括导致事件的元素,事件

的类型,以及其它与特定事件相关的信息。事件对象我们一般称作event对象,这个对象是浏览器通过函数把这个对

象作为参数传递过来的。那么我们可以验证一下:

<!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=gb2312" />
<title>DOM</title>
<script type="text/javascript">
//定义的普通函数
function box(){      
   alert(arguments.length);//输出:0  
};
//函数调用
box();

window.onload=function(){
    //得到input对象
    var input=document.getElementsByTagName("input")[0]; 
    //匿名函数执行 
    input.onclick=function(){
          alert(arguments.length);//输出:1,得到一个隐藏的参
          alert(arguments[0]);//输出:object MouseEvent表示鼠标事件对象
    };
}
</script>
</head>

<body>
<input type="button" value="按钮" />
</body>
</html>

通过上面两组函数,我们得到,通过事件绑定的执行函数是可以得到一个隐藏参数的,说明浏览器会自动分配一

个参数,这个参数就是为event对象。我们是可以直接接受event对象的,W3C和IE分别用不同的方法得到:W3C的是

直接传递event对象作为参数,而IE需要使用window.evevt才能获取得到。

我们来做一下兼容:

window.onload=function(){
    //得到input对象
    var input=document.getElementsByTagName("input")[0]; 
    //匿名函数执行 
    input.onclick=function(event){
            var event=event||window.event;
            alert(event);//输出:object MouseEvent表示鼠标事件对象
    };
}

我们既然得到event对象,因此我们可以操作一些event对象的属性和方法:

标准Event属性



标准Event方法



由于DOM2级标准事件模型,IE9之前的低版本浏览器并不支持,IE9已经全面支持了。我们就不再做浏览器兼容

的属性和方法。在真正用到的时候我们再进行视情况而定的兼容。

三事件模型

(1)内联模型

内联模型是最传统接单的一种处理事件的方法。在内联模型中,事件处理函数是HTML标签的一个属性,用于处

理指定事件。虽然内联在早期使用较多,但是它是和html混写的,并没有与html分离,并且写入的代码数量很少,并

不实用。

下面看一个内联模型的示例:

<!--在HTML中把事件处理函数作为属性执行JS代码-->
<input type="button" value="按钮" onclick="alert('I am JS code!');" />

还有一个内联模型的应用,这个也实现了JS代码和HTML一定的分离,但还是属于内联模型。JS函数写在JS文件

中:

<!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=gb2312" />
<title>DOM</title>
<script type="text/javascript">
function box(){
   alert("I am JS code!");
}
</script>
</head>

<body>
<!--在HTML中把事件处理函数作为属性执行JS函数-->
<input type="button" value="按钮" onclick="box();" />
</body>
</html>


(2)脚本模型

由于内联模型违反了HTML与JavaScript代码层次分离的原则,为了解决这个问题,我们尝试在JavaScript中进行

事件处理,这样就产生了脚本模型。示例如下:

<!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=gb2312" />
<title>DOM</title>
<script type="text/javascript">
window.onload=function(){
    //得到input对象
    var input=document.getElementsByTagName("input")[0]; 
    //匿名函数执行 
    input.onclick=function(){      
         alert("I am JS code!");  
    };
}
</script>
</head>

<body>
<input type="button" value="按钮" />
</body>
</html>

通过匿名函数可以执行onclick事件,即可以直接触发对应的代码。还有另一种方式也可以实现,那就是通过指定

的函数名赋值的方式来执行函数,注意赋值的函数名不要带着括号。

和上面有区别的就是JS代码部分:

window.onload=function(){
    //得到input对象
    var input=document.getElementsByTagName("input")[0]; 
    //通过赋值指定的函数名执行 
    input.onclick=box;
	function box(){      
           alert("I am JS code!");  
    };
}

(3)DOM2级模型

在介绍DOM2模型之前我们的先了解什么是事件流。

事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元

素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围内的所有元素都会出发事件。事件流包括两种模

式:冒泡和捕获。

下面的图示很好的展示了事件流:



事件冒泡,是从里往外逐个触发。事件捕获,是从外往里逐个触发。现代浏览器默认情况下都是冒泡模型,我们

可以使用DOM2级模型的事件绑定机制手动定义事件流模式。

在所有的现代浏览器当中——除了IE9之前的版本,都实现了DOM2标准事件模型,这个事件模型规定:每一个

DOM元素所触发的事件都要经历三个阶段:捕获阶段;目标对象本身的事件处理程序调用阶段;冒泡阶段。

冒泡阶段:当文档元素上发生某个类型的事件时,他们会在文档树上向上传播,即调用父元素的相同类型的事件

处理函数。

捕获阶段:捕获阶段像是反向的冒泡阶段。最先调用window对象的捕获处理程序,然后是document对象的捕获处

理程序,接着是body对象的,再然后是Dom树向下,以此类推,直到调用事件目标元素的父元素的捕获事件处理程

序。在目标元素对象本身上注册捕获事件处理程序不会被调用。

在DOM2级标准事件模型中,为一个DOM元素绑定事件的方法是addEventListener()方法,这个方法要求传递三

个参数,第一个参数为一个字符串,表示事件的类型,如"click";第二个参数是一个函数,表示事件处理程序,浏览

器会默认为该函数传递一个事件对象也就是event对象;第三个参数是一个布尔值,布尔值为false表示此函数将注册

为冒泡事件处理程序(通常设置为false即可),如果值为true,表示此函数将注册为捕获事件处理程序。值得注意的

是,能通过多次调用addEventListener()方法为同一个对象注册同一事件类型的多个处理程序函数。当对象上发生事

件时,所有该事件类型的注册处理程序都会按照注册的顺序调用。

分析事件的触发过程,分两种情况:

1当目标元素不存在父元素或目标元素的父元素并没有注册与触发目标元素相同类型的事件时,事件模型的第一

和第三阶段是没有实际意义的,即不会发生任何的事情。

2当目标元素存在父元素且目标元素的父元素注册了与触发目标元素相同类型的事件时,事件模型的第一和第三

阶段就开始起作用了。

我们在这里看一个很简单的例子:

<!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=gb2312" />
<title>DOM</title>
<script type="text/javascript">
window.addEventListener("load",function(){
       alert("I am JS code!");
},false)
</script>
</head>

<body>
<input type="button" value="按钮" />
</body>
</html>

上面的addEventListener()方法IE9之前的低版本浏览器并不兼容,并且进行绑定的时候会有诸多的问题出现,IE

不支持捕获,只支持冒泡;IE添加事件不能屏蔽重复的函数;IE中的this指向的是window对象而不是DOM对象。可能

对于低版本的IE浏览器不兼容,但是IE9完全支持W3C中的事件绑定函数。对于怎么做到兼容,还是在具体的实际项

目中灵活应用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: