面試問到js的事件流,當時說的不是很清楚,現在覺得有必要把這個弄清楚。

事件捕獲和事件冒泡

事件流描述的是從頁面中接收事件的順序,也可理解為事件在頁面中傳播的順序。
事件流主要分為兩種,即事件捕獲和事件冒泡,這二者接受事件處理的順序不同。假設下面的程式碼:

<body>
    <div id="outer">
        <div id="inner"></div>
    </div>
</body>

這兩個事件流分別的是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;
        }
    }
}
.