javascript -- 事件--事件流-- 冒泡 --捕獲

javascript -- 事件

事件是js和用戶操做交互的橋樑,

JavaScript 有三種事件模型:內聯模型、腳本模型和 DOM2 模型javascript

內聯模型

這種模型是最傳統接單的一種處理事件的方法。在內聯模型中,事件處理函數是 HTML 標籤的一個屬性,用於處理指定事件。雖然內聯在早期使用較多,但它是和 HTML 混寫的,並無與 HTML 分離。前端

//在 HTML 中把事件處理函數做爲屬性執行 JS 代碼
    <input type="button" value="按鈕" onclick="alert('Lee');" /> //注意單雙引號

腳本模型

因爲內聯模型違反了 HTML 與 JavaScript 代碼層次分離的原則。爲了解決這個問題,我
們能夠在 JavaScript 中處理事件。這種處理方式就是腳本模型。
var input = document.getElementsByTagName('input')[0]; //獲得 input 對象
    input.onclick = function () { //匿名函數執行
    alert('Lee');
    };

直接接收 event 對象,是 W3C 的作法,IE 不支持,IE 本身定義了一個 event 對象,直接在 window.event 獲取便可。java

div.onclick = function (evt) {
    var e = evt || window.event; //實現跨瀏覽器兼容獲取 event 對象
    if(evt){
        //w3c代碼
    } else if (window.event) {
        //ie代碼
    }
        
    };

DOM2 級

模型定義了兩個方法,用於添加事件和刪除事件處理程序的操做:
addEventListener()和 removeEventListener()全部 DOM 節點中都包含這兩個方法,而且它們都接受 3 個參數;事件名、函數、冒泡或捕獲的布爾值(true 表示捕獲,false 表示冒泡)。程序員

div.addEventListener('click', function () {
    alert('Lee');
    }, false);
    div.addEventListener('click', function () {
    alert('Mr.Lee');
    }, false);

捕獲與冒泡

事件流分爲2種:
(1) 冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發
(2) 捕獲型事件(event capturing):事件從最不精確的對象(document 對象)開始觸發,而後到最精確(也能夠在窗口級別捕獲事件,不過必須由開發人員特別指定)chrome

支持W3C標準的瀏覽器在添加事件時用addEventListener(event,fn,useCapture)方法,基中第3個參數useCapture是一個Boolean值,用來設置事件是在事件捕獲時執行,仍是事件冒泡時執行。而不兼容W3C的瀏覽器(IE)用attachEvent()方法,此方法沒有相關設置,不過IE的事件模型默認是在事件冒泡時執行的,也就是在useCapture等於false的時候執行,因此把在處理事件時把useCapture設置爲false是比較安全,也實現兼容瀏覽器的效果。

js事件捕獲與冒泡原理圖

圖片描述

DOM事件流:同時支持兩種事件模型:捕獲型事件和冒泡型事件,可是,捕獲型事件先發生。兩種事件流會觸及DOM中的全部對象,從document對象開始,也在document對象結束。瀏覽器

W3c明智的在這場爭鬥中選擇了一個擇中的方案。任何發生在w3c事件模型中的事件,首是進入捕獲階段,直到達到目標元素,再進入冒泡階段

你能夠選擇是在捕獲階段仍是冒泡階段綁定事件處理函數,這是經過addEventListener()方法實現的,若是這個函數的最後一個參數是true,則在捕獲階段綁定函數,反之false(默認),在冒泡階段綁定函數。安全

固然IE做爲前端程序員的口誅筆伐者天然如上面所說只支持冒泡階段執行, 然而使人高興的是從IE9 微軟擁抱 w3c 隨着谷歌的崛起 chrome已經站到瀏覽器的半壁江山, IE678 逐步走出歷史, 無疑給是前端開發的福音函數