javascript
javascript系列之DOM(三)---事件
??? 事件是javascript跳動(dòng)的心臟,是DOM所有成分結(jié)合的萬金油。當(dāng)我們?cè)赪EB 上進(jìn)行某些交互時(shí),事件也就發(fā)生了。點(diǎn)擊某些內(nèi)容,鼠標(biāo)經(jīng)過特定元素,按下某些按鍵,改變窗口。當(dāng)然還可能是瀏覽器上某個(gè)頁(yè)面加載完畢。通過 javascript你可以監(jiān)聽特定事件的發(fā)生,為事件綁定處理函數(shù)。
| DOM事件流 |
??? 在DOM中,當(dāng)某一個(gè)特定的HTNL元素產(chǎn)生事件時(shí),該事件會(huì)在該元素節(jié)點(diǎn)與根節(jié)點(diǎn)之間按特定的順序傳播,所經(jīng)過的節(jié)點(diǎn)都會(huì)監(jiān)聽到該事件(但不一定執(zhí)行該 事件對(duì)應(yīng)的動(dòng)作,因?yàn)槲唇壎ㄊ录幚砗瘮?shù)),這個(gè)傳播過程就是DOM事件流。事件流有兩種事件順序:事件捕獲和事件冒泡。
冒泡型事件(event bubble):冒泡型事件最早由IE實(shí)現(xiàn),事件就像水中的氣泡,有目標(biāo)元素逐級(jí)向上冒,直到頂端的根節(jié)點(diǎn)
捕獲型事件(event capture):捕獲型事件有netscape實(shí)現(xiàn),它與冒泡剛好相反,事件從根節(jié)點(diǎn)逐級(jí)派送到目標(biāo)元素。
DOM標(biāo)準(zhǔn)事件模型:W3C這個(gè)紅娘將二者融合在一起就形成了DOM標(biāo)準(zhǔn)事件模型。先執(zhí)行捕獲,然后再冒泡(所以,若果一個(gè)處理函數(shù)既被綁定了捕獲型事件,又被綁定了冒泡型事件,那么這個(gè)事件處理函數(shù)會(huì)執(zhí)行兩次,而且先執(zhí)行捕獲型事件)。
?
| 事件監(jiān)聽器和事件處理函數(shù) |
???? 事件處理函數(shù)(有的地方叫做事件句柄,此稱謂容易和事件監(jiān)聽器混淆,個(gè)人不推薦),用于響應(yīng)某個(gè)事件而調(diào)用的函數(shù)。每一個(gè)事件都應(yīng)該對(duì)應(yīng)一個(gè)事件處理函數(shù) (理論上),否則就是做無用功,浪費(fèi)資源。事件發(fā)生時(shí),瀏覽器執(zhí)行對(duì)應(yīng)的事件處理函數(shù),從而實(shí)現(xiàn)頁(yè)面內(nèi)容和用戶操作的交互。我們認(rèn)為響應(yīng)點(diǎn)擊事件的處理函 數(shù)為onclick。事件處理函數(shù)的兩種分配方式:javascript和html(內(nèi)聯(lián)的事件處理函數(shù)方式早已經(jīng)過去,不再討論)中。如果在 javascript中分配事件處理函數(shù),首先需要獲得處理對(duì)象的引用,然后將函數(shù)綁定到對(duì)象的事件處理函數(shù)屬性上:
1 var link=document.getElementById("mylink"); 2 link.οnclick=function(){ 3 alert("I was clicked !"); 4 };??? 這種分配事件處理函數(shù)的特定是簡(jiǎn)單,但不能為同一事件綁定多個(gè)事件處理函數(shù)。鑒于此缺點(diǎn),現(xiàn)在大多數(shù)瀏覽器內(nèi)置了事件監(jiān)聽器來更全面的綁定事件處理函數(shù)。 在IE下的事件監(jiān)聽器是attachEvent(),W3C標(biāo)準(zhǔn)型的事件監(jiān)聽器是addeventListener()。
A:attachEvent()
?? 在IE下,每個(gè)元素和window對(duì)象都有兩個(gè)方法attachEvent和detachEvent方法。
element.attachEvent("onevent",eventListener);第一個(gè)參數(shù)是事件類型名,第二個(gè)參數(shù)是事件處理函 數(shù)。在IE下處理函數(shù)調(diào)用時(shí)this指向的不再是先前注冊(cè)事件的元素,而是window(window.event的使用)。還有一點(diǎn)就是事件前面要 加"on"。?element.attachEvent("onevent",eventListener)刪除事件監(jiān)聽器,參數(shù)一致。
B:addEventListener()
??? 在支持W3C標(biāo)準(zhǔn)事件監(jiān)聽器的瀏覽器,每個(gè)對(duì)象都可以使用addEventListener方法。該方法及支持冒泡型事件處理,也支持捕獲型事件處理。 elem.addEventListener(type,eventListener,capture),默認(rèn)情況下capture取false,即為冒 泡型事件處理。addEventListener方法接受三個(gè)參數(shù)。第一個(gè)是事件類型,不需要加"on",第二個(gè)是事件處理函數(shù),第三個(gè)是決定事件處理函 數(shù)在冒泡還是捕獲階段調(diào)用。移除事件已經(jīng)注冊(cè)的監(jiān)聽器用removeEventListener。 和注冊(cè)的時(shí)候參數(shù)一致element.removeEventListener('event',?eventListener,?useCapture);
| 跨瀏覽器的事件監(jiān)聽器 |
???? 既然IE和W3C注冊(cè)時(shí)間監(jiān)聽器的方案是不同的,對(duì)于支持addEventListener方法的瀏覽器,只要需要事件監(jiān)聽器腳本就都需要調(diào)用addEventListener方法;而對(duì)于不支持該方法的IE瀏覽器,使用事件監(jiān)聽器時(shí)則需要調(diào)用attachEvent方法。那么我們要兼容瀏覽器也不是什么困難的事,下面是具體的兼容瀏覽器的注冊(cè)事件監(jiān)聽器方案:
1 var eventUtil={ 2 //注冊(cè) 3 addHandler:function(elem,type,handler){ 4 if(elem.addEventListener){ 5 elem.addEventListener(type,handler,false); 6 }else if(elem.attachEvent){ 7 elem.attachEvent("on"+type,handler); 8 }else{ 9 elem["on"+type]=handler; 10 } 11 } 12 //移除 13 removehandler:function(elem,type,handler){ 14 if(elem.removeListener){ 15 elem.removeListener(type,handler,false) 16 }else if(elem.detachEvent){ 17 elem.detachEvent("on"+type,handler) 18 }else{ 19 elem["on"+type]=null; 20 } 21 } 22 }??? 當(dāng)事件發(fā)生的時(shí)候觸發(fā)事件處理函數(shù),W3C情況下,event對(duì)象將自動(dòng)在事件處理函數(shù)內(nèi)可用,這個(gè)對(duì)象包含了該事件的全部信息。但在IE下是通過全局對(duì)象window下的event屬性來包含這些信息的。跨瀏覽器在獲取事件對(duì)象和事件目標(biāo):
1 var eventUtil={ 2 handler:function(event){ 3 event=event||window.event 4 do somesthing 5 } 6 getTarget;function(event){ 7 return event,target||event.srcElement 8 9 } 10 }| 阻止事件默認(rèn)行為和阻止事件冒泡 |
???? 阻止事件冒泡,停止冒泡型事件的進(jìn)一步傳遞(取消事件傳遞不只是停止IE和DOM標(biāo)準(zhǔn)共有的冒泡型事件,我們還可以停止支持DOM標(biāo)準(zhǔn)瀏覽器的捕捉型事件,用stopPropagation()方法。
? ? 阻止事件的默認(rèn)行為,通常瀏覽器在事件處理完后會(huì)執(zhí)行與該事件關(guān)聯(lián)的默認(rèn)操作。例如,如果表單中input type 屬性是 “submit”,點(diǎn)擊后在事件傳播完瀏覽器就自動(dòng)提交表單。又例如,input 元素的 keydown 事件發(fā)生并處理后,瀏覽器默認(rèn)會(huì)將用戶鍵入的字符自動(dòng)追加到 input 元素的值中。
A:停止事件冒泡的處理方法(把此函數(shù)放在目標(biāo)元素處理函數(shù)的最后一行):
1 function stopHandle(event){ 2 event=event||window.event 3 if(event.stopPropagation){ 4 event.stopPropagation(); 5 }else{ 6 event.cancelBubble=true; 7 } 9 }B:阻止事件的默認(rèn)行為
1 function defaultHandle(event){ 2 event=event||window.event 3 if(event.preventDefault){ 4 event.preventDefault(); 5 }else{ 6 event.returnValue=false; 7 } 9 }| ?事件委托 |
??? 事件委托是建立在事件冒泡的基礎(chǔ)上的,有這么一個(gè)例子,如果你有一個(gè)多行的表格,在每個(gè)<tr>上綁定點(diǎn)擊事件是個(gè)非常影響性能的大問題。大 多數(shù)庫(kù)或者框架的做法是使用事件委托。事件委托將事件綁定在包含目標(biāo)元素的容器元素上,然后通過判斷點(diǎn)擊的目標(biāo)子元素來觸發(fā)相應(yīng)的事件。
1 var myTable=dcument.getElementById("tab"); 2 myTable.addEventListener(click,function(event){ 3 event=event||window.event; 4 var targetNode=event.target||event.srcElement 5 if(targetNode.nodeName.toLowerCase()=="tr"){ 6 alert("you have clicked"); 7 } 8 }) posted on 2014-05-10 19:46 NET未來之路 閱讀(...) 評(píng)論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/lonelyxmas/p/3720919.html
總結(jié)
以上是生活随笔為你收集整理的javascript系列之DOM(三)---事件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用python读写excel(xlrd、
- 下一篇: hdu 2255 奔小康赚大钱--KM算