由处理程序来监听某个动作,一旦某个动作发生,那么处理程序就作出响应,这就是观察者模式的简单案例。在JavaScript中,按钮一旦被点击(或者其他动作,拿点击按钮举例),就会有响应的处理程序进行响应,比如,点击按钮弹出一个对话框、鼠标滑过按钮会提示一行字等等,这就是JavaScript中要讲的事件,也属于经典的观察者模式。
在DOM树中,可能一个<button>元素属于一个<div>元素的子元素,而<div>又属于<html>的子元素。这个时候,点击<button>这个元素,<button>就会触发一个事件(或者一个动作),而<div>、<html>有可能也要接收到这个事件的信号。也就是说,你打了button一下,它的父亲、祖父都会感受到你的打击。这就是事件流。IE的事件流是事件冒泡流。
如:打了孙子一下,孙子感受到疼,然后父亲感知,最后爷爷感知,追本溯源,直到老祖宗感知。
骂了姓张的人,首先张姓的祖宗感到耻辱,接着张姓的爷爷、爸爸、自己分别感受到。
先发生事件捕获,传递到最深一层,由具体元素接收到事件,然后冒泡并处理程序。(下面讲到第10节事件对象的target属性时会具体解释这一现象)
诸如click、load、mouseover都是事件的名字。
事件处理程序的名字则在前面加on,比如:onclick、onload等。
示例:
1 <body> 2 <input type="button" value="Click Me" onclick="alert(‘Clicked‘)" /> 3 <!--双引号转义--> 4 <input type="button" value="Click Me" onclick="alert("Clicked")" /> 5 6 <script type="text/javascript"> 7 function showMessage(){ 8 alert("Hello world!"); 9 } 10 </script> 11 <input type="button" value="Click Me" onclick="showMessage()" /> 12 <!--防止在函数未加载时点击--> 13 <input type="button" value="Click Me" onclick="try{showMessage();}catch(ex){}" /> 14 </body>
<input>是元素,
onclick是事件处理程序的名字,跟value、type一样,是属性。
缺点:
1 <body> 2 <input type="button" id="myBtn" value="Click Me" /> 3 <input type="button" id="myRemoveBtn" value="Remove Event Handler" /> 4 <script type="text/javascript"> 5 var btn = document.getElementById("myBtn"); 6 //会在事件流的冒泡阶段处理 7 btn.onclick = function(){ 8 alert(this.id);//this指示当前元素 9 }; 10 11 var removeBtn = document.getElementById("myRemoveBtn"); 12 removeBtn.onclick = function(){ 13 btn.onclick = null;//删除事件处理程序 14 }; 15 </script> 16 </body>
IE9及其他主流浏览器支持DOM2级事件处理程序。
比如点击某个按钮,要弹出一个提示框,同时要按钮改变颜色,这时就需要同时添加两个事件处理程序。
<body> <input type="button" id="myBtn" value="Click Me" /> <p>This example won‘t work in Internet Explorer.</p> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.addEventListener("click", function(){ alert(this.id); }, false); /**第三个参数默认为false,表示在冒泡阶段触发。如果为true,表示在捕获阶段触发,true一般不会用*/ btn.addEventListener("click", function(){ alert("Hello world!"); }, false); </script> </body>
即:如果在函数中使用this,this指示当前元素
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; } }
在事件处理程序内部,对象this始终等于currentTarget的值,
而target则只包含事件的实际目标。
一般情况下,currentTarget都与target相等。
但是,假如<button>的父元素是<div>,你给<div>元素绑定了一个onclick,
那么这时,<div>元素是currentTarget值,而target是最终目标:<button>(向下捕获)。
由于按钮<button>上并未绑定onclick事件处理程序,
结果click事件就冒泡到了<div>,在那里事件得到处理。
IE中的事件对象与其他主流浏览器稍微不同,比如,使用DOM0级方法添加事件处理程序时,方法中传入的event对象是window对象的一个属性,event事件对象的目标对象属性为srcElement而非target等等。所以一般情况下会写一个跨浏览器的Util。
<meta http-equiv="content-type" content="text/html; charset=gb2312"/> <script type="text/javascript"> function show () { //火狐不支持window.event,所以加入"或"条件 var e=window.event||arguments.callee.caller.arguments[0]; if(e.keyCode==13){ alert("你按下了回车"); } } </script> <input onkeydown="show();" value="触发键盘试试">
在javascript中,添加到页面上的事件处理程序数量将直接影响到页面整体的运行性能。
每个函数都是对象,都会占用内存。
内存中的对象越多,性能就越差。
所以要利用好事件处理程序,比如使用事件委托等。
原文:http://www.cnblogs.com/mesopotamia/p/5186738.html