前面我們介紹了事件冒泡和事件捕獲兩種事件事件獲取方式,而W3C模型 是兩者中和。就是事件發(fā)生時(shí),先從頂層開始進(jìn)行事件捕獲,直到事件觸發(fā)到達(dá)了事件源元素。然后,再?gòu)氖录赐线M(jìn)行事件冒泡,直到到達(dá)document。
利用W3C DOM Leavl 2事件監(jiān)聽器,就是 addEventListener函數(shù)。我們可以自己選擇綁定事件時(shí)采用事件捕獲還是事件冒泡,方法就是綁定事件時(shí)通過addEventListener函數(shù),上面我們介紹過它的三個(gè)參數(shù)了:如果第三個(gè)參數(shù)若是true,則表示采用事件捕獲,若是false,則表示采用事件冒泡。
但是在一個(gè)支持W3C DOM的瀏覽器中,按照DOM Leavl 1綁定事件方式,采用的全都是事件冒泡方式。大多數(shù)時(shí)候,我們也是希望事件從內(nèi)部嵌套的的元素冒泡到外圍元素。
解決方案
以上我們介紹過 W3C DOM Leaval 2事件綁定中的addEventlistener,可以為元素添加多個(gè)事件,而且最后一個(gè)參數(shù)還支持事件冒泡或捕獲,IE6/7/8仍然沒有遵循標(biāo)準(zhǔn)而使用了自己專有的attachEvent,且不支持事件捕獲,所有事件都是發(fā)生在冒泡階段。
所以創(chuàng)建一個(gè)可重用。實(shí)現(xiàn)了DOM Leavl 2事件處理的事件處理函數(shù),但是,它還是要跨瀏覽器。如下經(jīng)典代碼
listenEvent函數(shù)代碼
function listenEvent(eventTarget, eventType, evrntHandler) { if (eventTarget.addEventListener){ eventTarget.addEventListener(eventType, evrntHandler, true);//IE9等其他現(xiàn)代瀏覽器 } else if (eventTarget.attachEvent){ eventType = "on"+eventType; eventTarget.attachEvent(eventType,evrntHandler) //IE6、7、8 } else {eventTarget["on" + eventType] = evrntHandler;}//IE5~ 個(gè)人覺得不寫也罷。 }
listenEvent函數(shù)使用
listenEvent(document,"click",processClick)
可重用的事件處理函數(shù)此處理函數(shù)接受3個(gè)函數(shù):目標(biāo)對(duì)象、事件(作為一個(gè)字符串),以及函數(shù)名稱。首先測(cè)試對(duì)象,看看它是否支持addEventListener(W3C DOM Leaval 2的事件監(jiān)聽方法),如果支持這個(gè)方法,就把事件映射到事件處理函數(shù)。回到代碼,因?yàn)镮E6、7、8不支持addEventListener,所以檢查是否支持attachEvent,記得前面加”on“,因?yàn)椴患?#8221;on“只是事件的名字,但是因?yàn)镮E6、7、8只支持向上冒泡,所以此方案中 addEventListener的第三個(gè)參數(shù)是false。最后為了兼容DOM leaval 0事件處理,還要加最后一行代碼。
使用W3C DOM Leavl 2處理事件事件監(jiān)聽不會(huì)有覆蓋之前綁定事件的現(xiàn)象,每個(gè)綁定的事件都會(huì)被執(zhí)行,不過 attachEvent 為元素增加的一系列事件不是以添加它們順序執(zhí)行的,而是以相反的順序觸發(fā)。最重要的是,采用事件監(jiān)聽給對(duì)象綁定方法后,可以解除相應(yīng)的綁定。跟以上代碼類似,removeEventListener跟addEventListener對(duì)應(yīng),detachEvent跟eventType對(duì)應(yīng),得到如下解決方案:
stopListening函數(shù)代碼
function stopListening(eventTarget, eventType, evrntHandler) { if (eventTarget.removeEventListener){ eventTarget.removeEventListener(eventType, evrntHandler, true);//IE9等其他現(xiàn)代瀏覽器 } else if (eventTarget.attachEvent){ detachEvent = "on"+eventType; eventTarget.detachEvent(eventType,evrntHandler) //IE6、7、8 } else {eventTarget["on" + eventType] = null;}//IE5~ }
stopListening(document,"click",processClick)
可重用的事件處理函數(shù)在DOM標(biāo)準(zhǔn)的事件卸載方式中需要注意的是:事件捕獲的參數(shù)。如果你的事件是注冊(cè)在捕獲階段,則卸載事件時(shí),必須將其指定為捕獲階段(true),否則無法卸載;如果你的事件注冊(cè)在注冊(cè)在冒泡階段,則必須將其指定為冒泡階段(false),否則同樣無法卸載。
現(xiàn)在,如果我們想停止監(jiān)聽一個(gè)事件,可以直接調(diào)用stopListening,同樣傳入3個(gè)參數(shù):目標(biāo)對(duì)象、事件和事件處理函數(shù)。