一.事件流
事件捕获-(处于事件目标阶段-事件冒泡)
1.处于事件目标阶段看成是事件冒泡的一部分,目标元素接收到事件
2.但实际上事件捕获阶段也会触发对象上的事件,两个阶段都会触发事件
二.事件处理程序
1.HTML事件处理程序
给元素添加事件处理程序特性,并将函数赋值给元素的事件处理程序特性或者直接传入可执行的JS代码
<input type="button" value="click me" onclick="showMessage()"> <script> function showMessage(){ alert("liu"); } </script>
由于HTML与JS代码紧密耦合,想更换事件的话要修改两个地方,所以用JS指定事件处理程序
2.JS指定事件处理程序
(1)DOM0级事件处理程序:
将匿名函数赋值给元素的事件处理程序属性
<input type="button" value="click me" id="myBtn"> <script> var btn=document.getElementById("myBtn"); btn.onclick=function(){ alert(this.id); }; </script>
DOM0级事件处理程序是在元素的作用域中运行,this指向元素的执行环境
DOM0级只能添加一个事件处理程序,所以要添加多个事件要用DOM2级事件处理程序
(2)DOM2级事件处理程序:
添加事件addEventListener():也是在元素的作用域中运行
<script> btn.addEventListener("click",function(){ alert(this.id); },false); btn.addEventListener("focus",function(){ alert("hello"); },false); //false表示事件在冒泡阶段触发 </script>
删除事件removeEventLister():
<script> //匿名函数是没法删除的,要将匿名函数赋值给一个变量 var handler=function(){ alert(this.id); }; btn.addEventListener("click",handler,false); //添加 btn.removeEventListener("click",handler,false); //删除 </script>
IE事件处理程序:(IE9以前IE没有用DOM2级事件处理程序,但有与DOM类似的方法)
添加事件attachEvent():事件处理程序会在全局作用域中运行
<script> btn.attachEvent("onclick",function(){ //这里是onclick,而不是click alert(this==window); //true }); </script>
删除事件detachEvent()
<script> //同样匿名函数是没法删除的,要将匿名函数赋值给一个变量 var handler=function(){ alert(this.id); }; btn.attachEvent("onclick",handler); //添加 btn.detachEvent("onclick",handler); //删除 </script>
(3)跨浏览器的事件处理程序:
<script> 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; } } }; </script>
三.事件对象
当事件触发的时候会产生一个事件对象event,包含了与事件有关的信息:事件类型,导致事件的元素,以及其他特定事件有关的信息(例如鼠标导致的事件,event会包含鼠标的位置信息)
1.DOM中的事件对象
比较常用的信息:type,target(目标元素),currentTarget(正在处理事件的元素,this始终指向currentTarget)
无论是DOM0级,还是addEventListener()方法,event都可以作为参数传入到事件处理程序当中
在一个元素上用一个函数处理多个类型的事件:
var btn=document.getElementById("myBtn"); var handler=function(event){ switch(event.type){ case "click": alert(document.title); break; case "focus": alert(event.target.style.backgroundColor="yellow"); break; case "mouseover": alert(event.target.style.backgroundColor=""); break; default: } }; btn.onclick=handler; btn.onfocus=handler; btn.onmouseover=handler;
2.IE中的事件对象
type,srcElement(事件目标)
this要看情况,如果是DOM0级,指向目标元素,attachEvent()方法,指向window
对于DOM0级,event对象作为window对象的一个属性存在
var btn=document.getElementById("myBtn"); btn.onclick=function(){ var event=window.event; alert(event.type); //click };
对于attachEvent()方法,event可以作为参数传入事件处理程序中,也可以通过window.event得到
btn.attachEvent("onclick",function(event){ alert(event.type); });
3.跨浏览器的事件对象
var EventUtil={ getEvent:function(event){ return event?event:window.event; }, getTarget:function(event){ return event.target||event.srcElemnt; } };
四.事件类型
1.UI事件
load事件
两种定义onload事件处理程序的方式
(1)在<body>元素上添加onload特性:
<body onload=”alert(loaded!)”>
(2)用JS指定事件处理程序:
EventUtil.addHanler(window,"load",function(event){ alert("loaded!"); });
建议用JS方法
实际应用中,可以在页面加载完之后,预先加载图像 var img=new Image();
unload事件
一般用于清理内存
2.焦点事件
focus,blur
<form method="post"> <input type="text" name="username" value=""> <input type="button" value="Echo Username" onclick="alert(username.value)"> </form> <script> var text=document.getElementsByName("username")[0]; text.addEventListener("focus",function(event){ event.target.style.backgroundColor=""; },false); text.addEventListener("blur",function(event){ event.target.style.backgroundColor="yellow"; },false); </script>
五.内存
1.事件委托技术
将一类事件写成一个事件处理程序,并添加到DOM高层次的元素上
<ul id="myLinks"> <li id="goSometing">go something</li> <li id="doSomething">do something</li> <li id="saySomething">saySometing</li> </ul> <script> var links=document.getElementById("myLinks"); EventUtil.addHandler(links,"click",function(event){ event=EventUtil.getEvent(event); var target=EventUtil.getTarget(event); switch(target.id){ case "goSomething": location.href="baidu"; break; case "doSomething": document.title="liu"; break; case "saySomething": alert("liu"); break; } }); </script>
2.清理内存:移除事件处理程序
(1)使用innerHTML时,被替换部分元素中的事件处理程序依然在内存中,要手动清除
btn.onclick=function(){ //执行操作 btn.onclick=null; //执行完之后移除事件处理程序 document.getElementById("myDiv").innerHTML=""; };
(2)卸载页面的时候,事件处理程序依然会在内存中
EventUtil.addHandler(window,"unload",function(){ links.onclick=null; });
六.模拟事件
//用到的时候再看