JavaScript高级程序设计学习笔记--事件
HTML事件处理程序
<input type="button" value="Click Me" onclick"showMessage()"/>
通过HTML指定事件处理程序的的缺点是HTML与JavaScript代码紧密耦合。如果要更换事件处理程序,就要改动两个地方:HTML代码和JavaScript代码。
DOM0级事件处理程序
var btn=document.getElementById("myBtn"); btn.onclick=function(){ alert("Clicked"); }
在此,我们通过文档对象取得了一个按键的引用,然后为它指定了OnClink事件处理程序。但要注意,在这些代码运行以前不会指定事件处理程序,因此如果这些代码在页面中位于
按键后面,就有可能在一段时间内怎么单击都没有反应。
使用DOM0级方法指定的事件处理程序被认为是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行;换句话说,程序中的this引用当前元素。来看一个例子:
var btn=document.getElementById("myBtn"); btn.onclick=function(){ alert(this.id); //"myBtn" }
也可以删除DOM0级方法指定的事件处理程序,只要像下面这样将事件处理程序属性的值设置为Null即可:
btn.onclick=null;
DOM2级事件处理程序
"DOM2级事件"定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener();
使用DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。
var btn=document.getElementById("myBtn"); btn.addEventListener("click",function(){ alert(this.id); },false); btn.addEventListener("click",function(){ alert("hello world!"); },false);
这里为按钮添加了两个事件处理程序。这两个事件处理程序会按照添加它们的顺序触发。
通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除;移除时传入的参数与添加处理程序时使用的参数相同。这也意味着通过addEventListener()
添加的匿名函数无法移除,如下面所示:
var btn=document.getElementById("myBtn"); btn.addEventListener("click",function(){ alert(this.id); },false); btn.removeEventListener("click",function(){ //无效 alert(this.id); },false);
有效的:
var btn=document.getElementById("myBtn"); var handler=function(){ alert(this.id); } btn.addEventListener("click",handler,false); btn.removeEventListener("click",handler,false); //有效
IE事件处理程序
IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。
事件对象
兼容DOM的浏览器会将一个event对象传入到事件处理程序中。无论指定事件处理程序使用什么方法(DOM0级或DOM2级),都会传入event对象。来看下面的例子:
var btn=document.getElementById("myBtn"); btn.onclick=function(event){ alert(event.type); //"click" }; btn.addEventListener("click",function(event){ alert(event.type); //"click" },false);
在需要通过一个函数处理多个事件时,可以使用type属性,例如:
var btn=document.getElementById("myBtn"); var handler=function(event){ switch(event.type){ case "click": alert("Clicked");break; case "mouseover": alert("mouseover");break; case "mouseout": alert("mouseout");break; } } btn.onclick=handler; btn.onmouseover=handler; btn.onmouseout=handler;
要阻止特定事件的默认行为,可以使用preventDefault()方法。
var link=document.getElementById("myLink"); link.onclick=function(event){ event.preventDefault(); }
只有cancelable属性设置为true的事件,才可以使用preventDefault()来取消默认行为。
事件类型
只要用户从一个页面切换到另一个页面,就会发生unload事件 。
只有在同一个元素上相继触发mousedown事件和mouseup事件,才会触发click事件。
DOM的button属性可能有如下3个值:0表示主鼠标按钮,1表示中间的鼠标按钮(滚轮),2表示次鼠标按钮
keydown:当用户按下键盘上的做任意键时触发,而且如果按住不放的话,会重复触发些事件。
事件委托
对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。例如,click事件会一直冒泡到
document层次。也就是说,我们可以为整个页面指定一个onclick事件处理程序,而不必给每个可单击的元素分别添加事件处理程序。以下面的代码为例:
<ul id="myLinks"> <li id="goSomewhere">Go somewhere</li> <li id="doSomething">Do something</li> <li id="sayHi">Say Hi </li> </ul>
var list=document.getElementById("myLinks"); EventUtil.addHandler(list,"click",function(event){ event=EventUtil.getEvent(event); var target=EventUtil.getTarget(event); switch(target.id){ case "doSomething": document.tile="i changed the document's title";break; case "goSomewhere": location.href="http://www.wrox.com";break; case "sayHi": alert("hi");break; } }
最适合采用事件委托技术的事件包括click,mousedown,mouseup,keydown,keyup,keypress.