js事件流

兩種事件流事件捕獲和事件冒泡

冒泡事件流

當事件在某一DOM元素被觸發時,例如用戶在客戶名字節點上點擊鼠標,事件將跟隨着該節點繼承自的各個父節點冒泡穿過整個的DOM節點層次,直到它遇到依附有該事件類型處理器的節點,此時,該事件是onclick事件。在冒泡過程當中的任什麼時候候均可以終止事件的冒泡,在聽從 W3C標準的瀏覽器裏能夠經過調用 事件對象上的stopPropagation()方法,在Internet Explorer裏能夠經過設置事件對象的cancelBubble屬性爲true。若是不中止事件的傳播,事件將一直經過DOM冒泡直至到達文檔根。
若是想建立一個捕捉事件,在支持W3C 事件模型的瀏覽器中,將 addEventListener的第三個參數設爲true就行了。例如:
前一陣由於想弄懂事件捕捉,因此作了點小實驗,分別在Firefox 二、Safari 3 on Windows和Opera 9上實踐了事件捕捉(固然,由於IE不支持事件捕捉,因此…),實驗的原理見下圖:
ID爲div1和div2的兩個元素都被委派了捕捉階段的事件處理函數,這樣:
當點擊#div1(藍色區域)時,應該會 alert出」div1″
當點擊#div2(黃色區域)時,應該會先alert出」div1″,再alert出」div2″,由於在事件捕捉階段,事件是從根元素向下傳播的,#div1是#div2的父元素,天然綁定在#div1上的 click事件也會先於#div2上的click事件被執行
然而,以上的設想只適用於Firefox 2和Safari 3 on Windows,在Opera 9中,事情會變成這樣:
當點擊#div1(藍色區域)時,什麼都不會發生
當點擊#div2(黃色區域)時,會alert出」div1″,隨後什麼都不會再發生
 

捕獲事件流

事件的處理將從DOM層次的根開始,而不是從觸發事件的目標元素開始,事件被從目標元素的全部祖先元素依次往下傳遞。在這個過程當中,事件會被從文檔根到事件目標元素之間各個繼承派生的元素所捕獲,若是事件監聽器在被註冊時設置了useCapture屬性爲true,那麼它們能夠被分派給這期間的任何元素以對事件作出處理;不然,事件會被接着傳遞給派生元素路徑上的下一元素,直至目標元素。事件到達目標元素後,它會接着經過DOM 節點再進行冒泡。
事件流描述的是從頁面中接收事件的順序,也可理解爲事件在頁面中傳播的順序。
事件流主要分爲兩種,即事件捕獲和事件冒泡,這兩者接受事件處理的順序不一樣。假設下面的代碼:
<body>
    <div id="outer">
        <div id="inner"></div>
    </div>
</body>12345
這兩個事件流分別的是IE公司和netspace公司提出來的,冒泡事件流支持的瀏覽器更多。
冒泡事件流中,事件的傳遞順序是從子元素向父元素傳遞。假設咱們給div綁定一個click事件。那麼在冒泡事件流中,事件的傳遞順序是:inner->outer->body。然而捕獲事件流的順序則截然想法:body->outer->innner。
DOM事件流
DOM2級事件規定事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。仍是以上面的代碼爲例,單擊inner則會按照下面的順序觸發事件:document->html->body->outer->ineer->outer->body->html->document。在DOM事件流中,實際的目標inner在捕獲階段不會接受到事件。這意味着在捕獲階段,事件到outer就中止了,下一個階段是「處於目標」階段,因而事件在inner 上發生,並在事件處理中唄當作是冒泡階段的一部分。而後,冒泡階段發生,事件又傳播迴文檔。
事件處理程序
響應某個時間的函數叫作事件處理程序。DOM0級的事件處理程序很簡單,onclick就是經常使用的DOM0級事件處理函數,只會在冒泡階段被處理。
而DOM2級事件定義了兩個方法用於處理置頂和刪除事件處理程序的操做addEventListener()和removeEventListener(),全部DOM節點都包含這兩個方法,而且它們都接受3個參數:要處理的事件名,做爲事件處理的函數和一個布爾值。最後這個布爾值參數若是是true,表示在捕獲階段調用事件處理程序,反之則是在事件冒泡階段處理程序。DOM2級方法添加事件處理程序的好處是能夠添加多個事件處理程序,會按照添加順序被處理(不管是捕獲仍是冒泡)。
而IE不一樣的它有本身的方法attachEvent()和detachEvent,這兩個接受相同的兩個參數:事件處理程序名稱和事件處理程序函數。
跨瀏覽器的事件處理程序
 
var EventUtil = {
    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;
        }
    },
    removeHandler: function(element,type,handler) {
        if (element.removeEventListener)
        {
            element.removeEventListener(type,handler,false);
        }
        else(element.detachEvent) {
            element.detachEvent('on' +type,handler);
        }
        else {
            element['on'+type] = null;
        }
    }
}
相關文章
相關標籤/搜索