"事件是一種異步編程的實現(xiàn)方式雨饺,本質(zhì)上是程序各個組成部分之間的通信荐吉。
1、EventTarget接口
dom的事件操作(監(jiān)聽和觸發(fā))蝗拿,都定義在這個接口上晾捏。
該接口有三個方法:
addEventListener:綁定事件的監(jiān)聽函數(shù)
removeEventListener:移除事件的監(jiān)聽函數(shù)
dispatchEvent:觸發(fā)事件
1.1、addEventListener
格式:target.addEventListener(type,listener[,useCapture]);
"useCapture":監(jiān)聽函數(shù)是否在捕獲階段觸發(fā)哀托。默認為false(監(jiān)聽函數(shù)在冒泡階段觸發(fā))粟瞬。
addEventListener方法可以給當前對象的同一事件,添加多個監(jiān)聽函數(shù)萤捆,執(zhí)行順序是先添加先執(zhí)行裙品。但是如果監(jiān)聽函數(shù)也是同一個,則只執(zhí)行一次俗或。
1.2市怎、removeEventListener()
removeEventListener方法用來移除addEventListener方法添加的事件監(jiān)聽函數(shù)。
1.3辛慰、dispatchEvent()
當前節(jié)點觸發(fā)指定事件区匠,從未觸發(fā)監(jiān)聽的函數(shù)。這個方法類似于jQuery中的trigger方法,主動觸發(fā)某個element上的監(jiān)聽方法驰弄。
溫馨提示:上面說到了可以使用腳本去觸發(fā)一個事件的發(fā)生麻汰,那如果要區(qū)分這個事件是用戶真實觸發(fā)還是腳本觸發(fā)該怎么辦呢?可以使用event對象下的 isTrusted 屬性戚篙。event.isTrusted:用戶觸發(fā)的事件返回true五鲫,腳本觸發(fā)的返回false。
2岔擂、監(jiān)聽函數(shù)
dom提供三種方式位喂,用來為事件綁定監(jiān)聽函數(shù)。
2.1乱灵、on-屬性
就是行內(nèi)點擊事件塑崖,<div onclick="myClick()">點我</div>
2.2、element節(jié)點的事件屬性
window.onload=doSomething;
div.onclick=function(event){console.log('觸發(fā)事件');};
使用這個方法指定的監(jiān)聽函數(shù)痛倚,只會在冒泡階段觸發(fā)规婆。
2.3、addEventListener方法
使用 html標簽 on-屬性蝉稳,違反了html和js代碼分離原則聋呢;使用 element節(jié)點的事件屬性 的缺點是,同一個事件只能定義一個監(jiān)聽函數(shù)颠区,也就是說削锰,如果定義兩次onclick屬性,后一次定義會覆蓋前一次毕莱。因此器贩,這兩種方法都不推薦使用。
推薦使用 addEventListener 有點如下:
①朋截、可以針對同一個事件蛹稍,添加多個監(jiān)聽函數(shù)。
②部服、能夠指定在哪個階段(捕獲階段還是冒泡階段)觸發(fā)回監(jiān)聽函數(shù)唆姐。
③、除了DOM節(jié)點廓八,還可以部署在window奉芦、XMLHttpRequest等對象上面剩瓶,等于統(tǒng)一了整個JavaScript的監(jiān)聽函數(shù)接口腊凶。
2.4乃沙、this對象的指向
使用addEventListener 觸發(fā)函數(shù)中的this指向 element對象矾芙。
使用on-屬性,觸發(fā)函數(shù)中的this不會指向觸發(fā)事件的元素節(jié)點劫拢。
3褐奥、事件傳播
3.1仰挣、事件傳播的三個階段
事件在dom之間傳播有三個階段:捕獲階段、目標階段伸蚯、冒泡階段
事件傳播的最上層對象是window摩渺,接著依次是document,html(document.documentElement)和body(document.dody)剂邮。也就是說摇幻,如果元素中有一個
元素,點擊該元素抗斤。事件的傳播順序囚企,在捕獲階段依次為window丈咐、document瑞眼、html、body棵逊、div伤疙,在冒泡階段依次為div、body辆影、html徒像、document、window蛙讥。
注意锯蛀,用戶點擊網(wǎng)頁的時候,瀏覽器總是假定click事件的目標節(jié)點次慢,就是點擊位置的嵌套最深的那個節(jié)點(嵌套在節(jié)點的節(jié)點)旁涤。所以,最底層那個節(jié)點的捕獲階段和冒泡階段迫像,都會顯示為target階段劈愚。
如果希望事件到某個節(jié)點為止,不再傳播闻妓,可以使用事件對象的stopPropagation方法菌羽。
4、自定義事件和事件模擬
除了瀏覽器預定義的那些事件由缆,用戶還可以自定義事件注祖,然后手動觸發(fā)。
這種方式IE不支持均唉。
5氓轰、事件冒泡
e.preventDefault(); // 只阻止事件的默認行為,但不能阻止事件往上冒泡浸卦。
window.event.returnValue = false; //IE中阻止函數(shù)器默認動作的方式?
e.stopPropagation(); // 可以阻止事件冒泡
e.cancelBubble = true; // IE下阻止事件冒泡
比較暴力的方式有:
return false; // 阻止事件冒泡
擴展:
e.stopImmediatePropagatio() //同一節(jié)點添加多個點擊事件時署鸡,使用這個API可以控制后續(xù) handle是否執(zhí)行
Keeps the rest of the handlers from being executed and prevents the event from bubbling up the DOM tree.
比如一個 div 添加?addEventListener? click事件,添加兩次,當我們點擊這個div時靴庆,這兩個監(jiān)聽事件都會執(zhí)行时捌,那能不能控制在第一個監(jiān)聽回調(diào)函數(shù),控制第二個回調(diào)函數(shù)不執(zhí)行呢炉抒?可以奢讨。在第一個回調(diào)函數(shù)執(zhí)行?e.stopImmediatePropagatio() ,第二個函數(shù)就不會執(zhí)行了