一、如何理解JavaScript事件?
个人理解是浏览器或鼠标或键盘触发某个行为而产生的交互。它可能是某种鼠标行为(点击、按下、划过。。。。),也可能是某种键盘操作,亦或是浏览器发生的行为(文档加载完成,页面拉伸。。。);通过利用js可以监听特定事件的发生,并作出响应。
二、事件的触发----事件流
事件流指的是页面接收事件的顺序。当一个时间发生时,这个事件的传播过程就是事件流。
先来看张图,理解事件传播过程。
1.事件冒泡
事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。对于html来说,就是当一个元素产生了一个事件,它会把这个事件传递给它的父元素,父元素接收到了之后,还要继续传递给它的上一级元素,就这样一直传播到document对象(现代浏览器到window对象,只有IE8及下不这样);
现在的浏览器默认是采用的是事件冒泡;在DOM0级方法绑定事件只能是事件冒泡,不能设置;在DOM2级你可以设置是用事件冒泡还是事件捕获(下面说到事件处理程序时会介绍);
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Examples</title> <meta name="description" content=""> <meta name="keywords" content=""> <link href="" rel="stylesheet"> <style> /*html,body{height: 100%;width:100%;}*/ p{line-height: 30px;color:#f3e;} #div{width:50%;height: 120px;background: #eee;border:5px solid #f00;} #id{width:60%;height: 60px;margin:0 auto;background: #eff;border:5px solid #000;} </style> </head> <body id="body"> <p>冒泡过程示范</p> <div id="div"> id="div" <div id="id">id="id"</div> </div> <script> function $(id){ return document.getElementById(id); } var body = $("body"),div = $("div"),id = $("id"); /* 下面 我依次给对象window,body,div,id绑定了Dom0级事件click事件 */ window.onclick = function(){ alert("我是window"); } body.onclick = function(){ alert("我是祖先body"); } div.onclick = function(){ alert("我是父元素div"); } id.onclick = function(){ alert("我是子元素id"); } /* 当我在页面的id对象进行鼠标点击之后 会触发 alert("我是子元素id")-->alert("我是父元素div")-->alert("我是祖先body")-->alert("我是window"); */ /* 当我在页面的div对象处进行鼠标点击之后 会触发 alert("我是父元素div")-->alert("我是祖先body")-->alert("我是window"); */ /* 当我在页面的body对象内部进行鼠标点击之后 会触发 alert("我是祖先body")-->alert("我是window"); */ /* 当我在浏览器里面body的外部进行鼠标点击之后 会触发 alert("我是window"); */ </script> </body> </html>
#id点击事件分析:
如上图所示,鼠标点击到#id上 触发冒泡过程。先执行6的事件处理函数 在依次执行7-8-9-10;
2.事件捕获
捕获阶段是一个和冒泡阶段完全相反的过程,即事件由祖先元素向子元素传播的过程。
事件捕获在现代浏览器中是由addEventListener(event,fn,useCapture)方法中第3个参数useCapture来决定的。它是一个Boolean值,当这个布尔值为true
时,表示在捕获阶段调用事件处理程序;如果是false
,表示在冒泡阶段调用事件处理程序。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 6 <title>Examples</title> 7 <meta name="description" content=""> 8 <meta name="keywords" content=""> 9 <link href="" rel="stylesheet"> 10 <style> 11 /*html,body{height: 100%;width:100%;}*/ 12 p{line-height: 30px;color:#f3e;} 13 #div{width:50%;height: 120px;background: #eee;border:5px solid #f00;} 14 #id{width:60%;height: 60px;margin:0 auto;background: #eff;border:5px solid #000;} 15 </style> 16 </head> 17 <body id="body"> 18 <p>冒泡过程示范</p> 19 <div id="div"> 20 id="div" 21 <div id="id">id="id"</div> 22 </div> 23 <script> 24 function $(id){ 25 return document.getElementById(id); 26 } 27 var body = $("body"),div = $("div"),id = $("id"); 28 /* 29 下面 我依次给对象window,body,div,id绑定了Dom2级事件click事件 30 */ 31 window.addEventListener("click", function(){ 32 alert("我是window"+"捕获"); 33 },true); 34 window.addEventListener("click", function(){ 35 alert("我是window"+"冒泡"); 36 },false); 37 body.addEventListener("click", function(){ 38 alert("我是祖先body"); 39 },true); 40 div.addEventListener("click", function(){ 41 alert("我是父元素div"); 42 },true); 43 id.addEventListener("click", function(){ 44 alert("我是子元素id"+"捕获"); 45 },true); 46 id.addEventListener("click", function(){ 47 alert("我是子元素id"+"冒泡"); 48 },false); 49 50 </script> 51 </body> 52 </html>
#id点击事件分析:
如上图所示,鼠标点击到#id上 既触发捕获又触发冒泡过程。他依次执行的是1-2-3-4-5-6-10;
#div点击事件分析:
如上图所示,鼠标点击到window上 既触发捕获又触发冒泡过程。他依次执行的是1-2-3-10;
window点击事件分析:
如上图所示,鼠标点击到window上 既触发捕获又触发冒泡过程。他依次执行的是1-10;
说一句怪异的话:是否触发捕获阶段的调用事件 ,并不是全由当前事件的作用对象决定,而是由此对象或它的父元素是否绑定了接收捕获的监听事件决定。但无论如何 在这一过程中 都存在着事件捕获和冒泡的的流程。(我把这一过程理解为事件流,如果理解不当 望各位指正);
三、事件处理程序
1.HTML事件处理程序
直接在页面元素中添加时间处理程序,这种方式是嵌套在元素里面的。例如:
<input type="text" id="inp" value="" onclick="setVal(this,'阿斯达')"> <script> function setVal(obj,str){ obj.value = str; } </script>
2.DOM0级事件处理程序
为指定对象添加事件处理。例如:
<input type="text" id="inp" value="" > <script> var inp = document.getElementById("inp"); inp.onclick =function (){ this.value = '阿斯达'; } </script>
3.DOM2级事件处理程序
DOM2级事件定义了两个方法:用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。它们都接收三个参数:要处理的事件名、作为事件处理程序的函数和一个决定是捕获还是冒泡的布尔值。例如:
<input type="text" id="inp" value="" > <script> var inp = document.getElementById("inp"); inp.addEventListener("click",function(){ this.value = '阿斯达'; },false) </script>
事件处理程序演变的原因:第一种HTML事件处理程序耦合性太强 不利于后期修改,第二种DOM0事件处理程序每个事件每次只能绑定一个事件处理函数,无法满足多个要求,第三个DOM2事件处理程序的出现解决了多个事件处理函数绑定同一个事件。而且还增加了事件在捕获阶段处理函数的能力。
以上总结借鉴了网上的资料也添加了些个人的理解。如果有理解不当的地方 望指正。