静态网站跟动态网站最大的区别就是动态网站能与用户产生交互,能处理数据。在互联网的早期,访问internet的方式与我们现在又很大的不同,那个时候的宽带是很小的,如果要处理验证,往返服务器要很长事件的等待,javascript当时设计就是为了解决这个问题,我们可以在前端直接做验证,就节省了往返服务器的时间。我们用户与html的交互可以通过javascript,纽带就是事件,比如,点击按钮就是一个事件,我们可以在时间处理程序,通俗的讲就是事件回调函数,即我们处理事件的函数里面写我们的脚本,达到交互的效果。
事件流
那什么是事件流,事件流其实就是事件执行的方向,比如代码
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title> </title> <script type="text/javascript"> function SayHello() { alert("Hello World"); } </script> </head> <body> <form id="form1" runat="server"> <div onclick="SayHello()" style="300px; height:300px; background-color:Green"> <input type="button" value="click me" onclick="SayHello()" /> </div> </form> </body> </html>
如果我们点击button,则会弹出两次Hello World,因为,button实际上是在div内,我们点击button的时候同时也在点击div。所以同时会触发button的onclick事件,也会触发div的onclick事件。那它们谁先触发谁后触发呢,触发的顺序其实就是事件流。IE的事件流为冒泡事件流。从最里层的元素开始触发,一直到document元素。Mozilla同IE一样,但是它会一直触发到window对象,netscape的事件流与IE刚好相反,它是从最外层开始触发,一直到最里层元素。DOM的事件流是同时支持这两种。
事件监听函数
其实我更喜欢叫事件处理函数,就是处理这个事件所要执行的功能(函数)。每个事件都有自己的名字,比如onclick,onclick就是事件,然后需要一个函数来处理这个事件。分配时间处理函数有两种方法,第一种是先得到元素也就是对象的引用。然后分配函数
function GetEvent() { var obutton = document.getElementById("Edrick"); obutton.onclick = SayHello; }
需要注意的是,如果采用这样的方式处理事件,那么事件名必须小写,另外的一种方式是直接在元素上声明特性,用函数名用作特性的值,不区分大小写
<input type="button" id="Edrick" value="click me" onclick="SayHello()" />
这里我们做的都是分配一个事件处理函数,但是如果我们想为一个事件分配多个事件处理函数呢?IE跟DOM的做法是不一样的,我们先看看IE的做法。
在IE中每个元素和window对象都有两个方法,一个是attachEvent()和detachEvent().顾名思义, attachEvent()用来给一个事件附加事件处理函数, detachEvent().用来将事件处理函数分离出来。
function GetEvent() { var obutton = document.getElementById("Edrick"); obutton.attachEvent("onclick", FEvent1); obutton.attachEvent("onclick", FEvent2); } function FEvent1() { alert("Checked"); } function FEvent2() { alert("also Checked"); }
测试代码会弹出两个系统框
然后我们可以把函数分离出来
function GetEvent() { var obutton = document.getElementById("Edrick"); obutton.attachEvent("onclick", FEvent1); obutton.attachEvent("onclick", FEvent2); obutton.detachEvent("onclick", FEvent2); }
这样就会只弹出一个系统框了
DOM提供的方法是addEventListener()和 removeEventListener(),他们的用法跟IE上的差不多,唯一的不同就是它们需要提供3个参数,第三个参数指明事件流,true为从外到里的事件流,false则为从里到外的事件流。还要注意点的是,如果在addEventListener()中指明的事件流是冒泡,那么在removeEventListener()的时候,第三个参数也应该为冒泡,必须一致才能正确的删除事件。如果不这样做,虽然不会出错,但是函数也不会正确的删除
事件对象
有时候我们需要知道或者获取事件触发时候的一些信息,比如
引起事件的对象
事件发生时的一些我们需要的信息(鼠标坐标,键盘键位等)事件对象只有在事件发生时才被创建,而且只有事件处理函数可以访问。所有的事件函数执行完毕后,事件对象就销毁
IE和DOM不同,我们先看IE获取事件对象的方法
在IE中事件对象是window的一个属性event,尽管它是window对象的属性,但是它也只能在事件发生时访问。
function SayHello() { var oevent = window.event; alert("Hello World"); }
在DOM中,事件对象必须作为参数传递给处理函数
function SayHello() { var oevent = arguments[0]; alert("Hello World"); }
当然,这里也可以直接传进来
function SayHello(event) { var oevent = event alert("Hello World"); }
属性/方法
事件对象的属性和方法可以让我们得到特定的信息,注意,特定属性只对特定的事件,IE跟DOM的属性有差别
IE
DOM属性/方法
相似性
在IE跟DOM的事件对象属性中,有一些相似的属性
type //获取事件的类型,比如是onclick或者onmouseover
keyCode //获取按键的代码 (keydown/keyup)。回车键的keyCode为13,空格键的keyCode为32,回退的keyCode为8
shiftKey
altKey
ctrlKey //检测Shift,Alt,Ctrl是否按下
clientX
clientY //检测鼠标在客户端区域的位置
screenX
screenY //检测鼠标相对屏幕的位置
区别
检测事件源,触发时间的对象
IE:srcElement
DOM:target
获取字符代码
IE:IE使用属性keyCode获取字符代码(非Shift,Alt,Ctrl),IE的 keyCode会直接返回字符的代码(unicode值)
DOM:DOM使用charCode来获取,然后使用String.fromCharCode()来返回实际的字符,也可以在获取字符的时候使用isChar来判断按键是否包含字符
阻止事件的默认行为
IE:returnValue
DOM:preventDefault()
为什么要阻止事件的默认行为呢,典型的例子,我们阻止右键点击就需要
function LeftOrRight() { document.oncontextmenu = function () { alert("禁止右键点击"); var oevent = window.event; oevent.returnValue = false; setInterval("alert('将在2秒后关闭');window.close();",2000); } }
当然这里是IE的写法,DOM是不一样的。
停止事件流
IE:cancelBubble=true
DOM:stopPropagation()
事件类型
鼠标事件
onclick //用户单击鼠标左键时发生
dblclick //用户双击鼠标左键时发生
mousedown //用户单击任意一个鼠标按钮时发生
mouseout //鼠标指针在某个元素上,且用户正要将其移出元素的边界
mouseover //鼠标移出某个元素,到另一个元素上时发生
mouseup //用户松开任意一个按钮时发生
mousemove //鼠标在某个元素上时持续发生
对于mouseover和mouseout事件多出两个额外的属性,一个是fromElement和toElement,fromElement包含鼠标来自的元素,toElement包含鼠标去往的元素。
而在DOM中,只有一个属性,relatedTarget,在mouseover事件中,relatedTarget表示鼠标来自何处,在mouseout表示鼠标去往何处
键盘事件
keyDown //用户在键盘上按下某按键,一直按着某按键,它会不断触发
keypress //用户按下一个键,并产生一个字符时发生
keyup //用户释放按着的按键
HTML事件
load //页面完全载入后,在window对象上触发,所有的框架都载入后,在框架集上触发,<img>或某个<object>完全载入后,在其上触发
unload //页面完全卸载后,在window对象上触发,所有的框架都卸载后,在框架集上触发,<img>或某个<object>完全卸载后,在其上触发
abort //用户停止下载过程时,如果<object>对象还未完全载入,就在其上触发
error // javascript脚本出错时,在window对象上触发。某个<img>或某个<object>无法载入时触发
select //用户选择了文本框的一个或多个文件时触发
change //文本框市区焦点时,并且在它获得焦点后内容发生过改变时触发;某个<select>元素的值发生改变时触发
resize // 窗口或框架的大小发生改变时触发
scroll //用户在任何带滚动条的元素上触发时,我们可以使用body的属性 scrollLeft和scrollTop来保存水平和垂直的滚动距离。
focus //任何元素或窗口本身获取焦点时
blur //任何元素失去焦点时
其实我们可以写一个事件的帮助类来实现获取事件,事件的属性/方法来达到统一DOM和IE的效果。有兴趣可以自己实现,以后有时间我会开一篇专门实现