成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

整理DOM事件相關(guān)知識(shí)點(diǎn)

red_bricks / 2835人閱讀

摘要:事件相關(guān)內(nèi)容當(dāng)用戶與瀏覽器發(fā)生的一些交互時(shí)如果希望去獲得用戶行為就需要借助事件來完成事件部分內(nèi)容在中重要性不言而喻羅列需要了解與事件相關(guān)的知識(shí)如下這也是面試中遇到的問題事件的級(jí)別事件模型事件流事件處理程序描述事件捕獲冒泡的具體流程對(duì)象常見的

DOM事件相關(guān)內(nèi)容

當(dāng)用戶與瀏覽器發(fā)生的一些交互時(shí), 如果希望去獲得用戶行為, 就需要借助事件來完成. 事件部分內(nèi)容在 JS中重要性不言而喻.

羅列需要了解與事件相關(guān)的知識(shí)如下: 這也是面試中遇到的問題.

DOM 事件的級(jí)別

DOM 事件模型

DOM 事件流

DOM 事件處理程序

描述DOM事件捕獲(冒泡)的具體流程

Event對(duì)象常見的應(yīng)用

自定義事件

事件級(jí)別

DOM0

DOM2

DOM3

DOM 事件模型

事件冒泡

事件捕獲

什么是事件流

要想明白事件流,必須先懂的這幾個(gè)知識(shí)點(diǎn)

事件冒泡

事件捕獲

先來看一個(gè)有趣的問題, 這是 4 代瀏覽器(IE4)開發(fā)團(tuán)隊(duì)遇到一個(gè)的問題:

What part of the Webpage owns a specific event?

頁面的哪一部分會(huì)擁有某個(gè)特定的事件?

要想明白這個(gè)問題可以想象成在一個(gè)頁面上畫了一組同心圓, 當(dāng)手指放在中間時(shí),它不僅在一個(gè)圓圈內(nèi),而且在所有的圓圈內(nèi)。

如下圖所示:

這就是瀏覽器事件的工作原理, 當(dāng)你點(diǎn)擊一個(gè)按鈕時(shí), 不僅單擊按鈕,還單擊包含的容器和整個(gè)頁面。

事件生命周期, 分為三個(gè)階段: capturing (捕獲), target (目標(biāo)), bubbling (冒泡). 而這三個(gè)階段也是構(gòu)成事件流基本部分.

這種處理思想, 在現(xiàn)在流行 NodeJS 后端框架 Koa 對(duì)中間件的處理模式也是基于這種, 熟悉Koa或許對(duì)這洋蔥圖并不會(huì)陌生:

先來熟悉事件的模型:

Javascript Events: Event bubbing (事件冒泡)

事件冒泡: 既事件開始由最具體的元素接收,然后逐級(jí)向上傳播最后到達(dá) Document 對(duì)象 或 window 上.

先來看一個(gè)簡(jiǎn)單的示例, 代碼如下:

    
    
        
            ......
        
        
            
Press here.
    var target = document.getElementById("demo");
    window.addEventListener("click", function(){
        console.log("window bubbling");
    });
    document.addEventListener("click", function(){
        console.log("document bubbling");
    });
    document.documentElement.addEventListener("click", function(){
        console.log("html bubbling");
    });
    document.body.addEventListener("click", function(){
        console.log("body bubbling");
    });
    target.addEventListener("click", function(){
        console.log("target bubbling");
    });

控制臺(tái)打印輸出如下

    "target bubbling"
    "body bubbling"
    "html bubbling"
    "document bubbling"
    "window bubbling"

當(dāng)一個(gè)div 被點(diǎn)擊, 這點(diǎn)擊事件發(fā)生的順序如下:

div

body

html

Document

Window (現(xiàn)在瀏覽器中, IE9+, Firfox, Chrome 等)

從執(zhí)行順序來說, click事件首先在 div 元素上觸發(fā), 然后沿著DOM Tree 向上傳播, 在路徑上的每個(gè)節(jié)點(diǎn)上觸發(fā),直到它到達(dá)文檔對(duì)象(或Window對(duì)象)。

Javascript Events: Event Capturing (捕獲)

事件捕獲 是另外一種事件流模型, 最先由 Netscape Browser 引入.

根據(jù)上面的的模型, 剛好與前面冒泡相反. 根據(jù)該模型,最不特定(最外層)的節(jié)點(diǎn)首先接收事件,而最特定(目標(biāo)元素)的節(jié)點(diǎn)最后接收事件.

它設(shè)計(jì)的目標(biāo)就是在事件到達(dá)目標(biāo)之前,事先進(jìn)行攔截.

參考前面的示例, 修改下監(jiān)聽方式, 代碼修改如下:

    var target = document.getElementById("demo");
    window.addEventListener("click", function(){
        console.log("window Capturing");
    }, true);
    document.addEventListener("click", function(){
        console.log("document Capturing");
    }, true);
    document.documentElement.addEventListener("click", function(){
        console.log("html Capturing");
    }, true);
    document.body.addEventListener("click", function(){
        console.log("body Capturing");
    }, true);
    target.addEventListener("click", function(){
        console.log("target Capturing");
    }, true);

打印的結(jié)果:

    "window bubbling"
    "document bubbling"
    "html bubbling"
    "body bubbling"
    "target bubbling"

當(dāng)點(diǎn)擊 div 元素, 按照如下順序來進(jìn)行廣播事件.

Window (現(xiàn)在瀏覽器中, IE9+, Firfox, Chrome 等)

Document

Document

body

div

注意:

DOM0 級(jí)中默認(rèn)就是使用冒泡的方式, 不支持捕獲的. 所以在 DOM2 級(jí)中通過 addEventListener 提供的第三個(gè)參數(shù)來控制使用哪種事件流來處理.
Javascript Events: DOM Event Flow (事件流)

根據(jù)上面兩種模型, 可以總結(jié)完整事件流應(yīng)該向如下:

DOM Level 2 Events 指定的事件流模型分為三個(gè)階段:

Event Capturing Phase (事件捕獲階段)

At the target (目標(biāo)階段)

Event Bubbling Phase (事件冒泡階段)

從上面流程圖中, 首先發(fā)生的是 事件捕獲階段 為截獲事件提供了機(jī)會(huì), 再到目標(biāo)階段 然后進(jìn)入 事件冒泡階段, 可以在這個(gè)階段對(duì)事件進(jìn)行響應(yīng).

引用前面的例子, 點(diǎn)擊 DIV 元素時(shí), 事件將按照上圖順序進(jìn)行觸發(fā).

這就是完整的事件流, 內(nèi)容看起來挺多的, 實(shí)際上一句話就概述事件流.

用來描述事件發(fā)生順序(頁面接收事件順序).
事件處理方式

通過前面的知識(shí)點(diǎn), 事件就是表示用戶或?yàn)g覽器自身執(zhí)行某種動(dòng)作. 例如: click, dbclick, load, unload, mouseover,mouseout, mouseenter ,mouseleave 等等, 這些都是事件的名字. 而響應(yīng)并處理某個(gè)事件的函數(shù)稱為 事件處理程序.

常見事件處理方式包括如下幾種:

HTML 事件處理程序

DOM0 級(jí)處理程序

DOM2 級(jí)處理程序

HTML 事件處理程序

直接來看個(gè)簡(jiǎn)單示例:

    

這種模式, 可以理解為 CSS 行內(nèi)樣式,

    

直接在 HTML 元素上綁定相應(yīng)事件名, 并指定對(duì)應(yīng)的事件處理程序. 從前面語法來說, 事件處理程序是一個(gè)函數(shù), 上面?zhèn)鬟f是一個(gè)語句, 也就是說默認(rèn)執(zhí)行時(shí), JS引擎會(huì)進(jìn)行相應(yīng)處理. 等價(jià)于這種方式:

    

如果把事件處理函數(shù)直接以這種內(nèi)聯(lián)值的方式提供, 應(yīng)該注意不能值中指定未經(jīng)轉(zhuǎn)義的HTML語法字符 例如: 和號(hào)(&) 、雙引號(hào)("") 等等, 否則會(huì)解析出錯(cuò).

如上面示例,如果想使用雙引號(hào), 必須這么處理.

    

這種對(duì)于簡(jiǎn)單語句還行, 除了提供元素屬性值的方式, 那么有木有其它方式咧? 答案:當(dāng)然有 , HTML事件處理程序可以調(diào)用在頁面其它地方定義的腳本.

示例如下:

    
    

通過這種方式指定事件處理程序具有一些特別的地方.

前面講述事件處理程序引擎在執(zhí)行時(shí), 默認(rèn)封裝函數(shù). 在封裝的函數(shù)中包含一個(gè)局部變量 event, 也就是事件對(duì)象.

    
    

    // => 等價(jià)

    

該函內(nèi)部 this 指針表示是當(dāng)前的目標(biāo)對(duì)象

    

    // this === [object HTMLInputElement] === input元素
    

這樣可以通過 this來獲取目標(biāo)元素相關(guān)的內(nèi)容了. 比如取值

    
    
    

為什么可以簡(jiǎn)寫方式, input 對(duì)象是存在于當(dāng)前函數(shù)的作用域鏈中(scope). 為了調(diào)試方式, 把上面方式作如下改變

    

其實(shí)理解上面那句話, 我們可以借助開發(fā)這工具來協(xié)助理解:

從執(zhí)行棧(Call Stack)可以看出, 證明前面說的默認(rèn)會(huì)創(chuàng)建封裝函數(shù) .

從 Scope 作用鏈中可以看出, 前面說的 input 對(duì)象會(huì)被添加在當(dāng)前匿名函數(shù)執(zhí)行的作用域鏈上.

根據(jù)開發(fā)工具來看, 我們是可以模擬引擎幫做的事情, 偽代碼如下:

    function () {
        with(document) {
            with(input){
                // dosomething
                console.log(value);    
            }
        }
    }

本質(zhì)通過 with 來擴(kuò)展作用域.

上面把基本內(nèi)容說, 那么這種通過HTML事件處理程序有什么問題么 ?

時(shí)差問題

事件處理程序必須優(yōu)先元素加載, 有可能DOM加載出來, 用戶就開始操作, 此時(shí)事件處理程序可能未加載導(dǎo)致報(bào)錯(cuò)

前面提及擴(kuò)展程序的作用域鏈可能在不同瀏覽器中兼容不一樣,導(dǎo)致程序出現(xiàn)錯(cuò)誤

視圖和行為偶合在一起,也就是說事件處理程序修改相應(yīng)JS部分、HTML部分都需要去修改.

引用前面的示例:

    
    

如果用戶想把函數(shù)名為: "onClick", 這時(shí)是不是需要同時(shí)去修改.

DOM0 級(jí)事件處理程序

通過 JavaScript 來指定事件的處理程序, 也就是將一個(gè)事件處理程序賦值給一個(gè)元素屬性(事件類型).

語法

    element.onclick = function(){}

先看個(gè)簡(jiǎn)單示例:

    
    
    


    
    

上述就是 DOM0 級(jí)事件處理程序應(yīng)用.

使用 DOM0級(jí) 不同于 HTML事件處理程序 優(yōu)點(diǎn)在于:

把視圖和行為進(jìn)行解耦.

更容易讓人理解(作用域的各種問題)

DOM0 級(jí)添加事件有哪些特點(diǎn)

由于通過 target.onclick 這種方式是不是很熟悉, object.property , 那么意味這添加事件處理程序(方法) 屬于當(dāng)前 DOM元素的, 相應(yīng)其內(nèi)部 this 指向當(dāng)前元素.

    

    

打印輸出結(jié)果為:

   "ClickMe" 

從結(jié)果來看,是符合前面說的.

大家是否記得前面說事件流 提及事件兩個(gè)階段冒泡捕獲, 那么通過 DOM0級(jí)別 添加的事件會(huì)發(fā)生那個(gè)階段 ? 冒泡

通過簡(jiǎn)單示例來看看:

    

    

打印輸出結(jié)果:

    "input bubbling"
    "body bubbling"

細(xì)心讀者發(fā)現(xiàn), 在講解 事件捕獲 時(shí)提及了, 事件捕獲是 DOM2 級(jí)才進(jìn)行引入的. 也驗(yàn)證現(xiàn)在說法.

移除事件處理程序

簡(jiǎn)單粗暴, 也只能這樣.

    target.onclick = null;
同一個(gè)事件名添加多個(gè)處理程序

DOM0級(jí)中, 使用onclick 方式添加事件處理程序是不支持添加多個(gè), 假如有這樣場(chǎng)景需要自己去擴(kuò)充, 現(xiàn)在瀏覽器中基本使用 DOM級(jí)非常少了, 所以不必?fù)?dān)心.

簡(jiǎn)單實(shí)現(xiàn)如下:

    var target = document.querySelector("input");

    function handleOne() {
        console.log("handle one");
    }
    function handleTwo() {
        console.log("handle two");
    }

    function addEvent(eventName, target, handle) {
        var map = target.map ? target.map : target.map = {};
        if (typeof target.onclick === "function") {
            target.map[eventName].push(handle);
        } else {
            target.onclick = function () {
                map[eventName].every(function (fn) {
                    return fn();
                });
            };
            if (!map[eventName]) {
                map[eventName] = [];
            }
            map[eventName].push(handle);
        }
    }
    function removeEvent(eventName, target, handle) {
        var map = target.map;
        var list = [];
        if(!map){return;}
        if(list = map[eventName]) {
            var index = list.indexOf(handle);
            list.splice(index, 1);
        }
    }
    addEvent("onclick", target, handleOne);
    addEvent("onclick", target, handleTwo);

    removeEvent("onclick", target, handleOne)

兩個(gè)小細(xì)節(jié):

為什么迭代循環(huán)時(shí)為什么使用 every, 而不是用 forEach 、map、some; 這里先預(yù)留一個(gè)終止執(zhí)行隊(duì)列里面的條件, every 只有每一個(gè)數(shù)組元素滿足條件時(shí)才會(huì)往下執(zhí)行, 否則直接終止循環(huán).

因?yàn)樘砑訒r(shí)直接把事件處理程序添加在一個(gè)數(shù)組中, 刪除時(shí)只能通過函數(shù)引用; 所以在 addEvent 時(shí)不能通過匿名函數(shù)的方式. 否則無法被移除.

兼容性

所有瀏覽器都支持
DOM2 級(jí)事件處理程序

DOM2級(jí)事件定義了兩個(gè)方法, 用來指定和刪除事件處理程序的操作, 分別是 addEventListenerremoveEventListener.

語法:

target.addEventListener(type, listener[, options]);
target.addEventListener(type, listener[, useCapture]);    

target.removeEventListener(type, listener[, options]);
target.removeEventListener(type, listener[, useCapture]);

type

表示事件的類型的字符串

listener

事件處理程序必須是一個(gè)實(shí)現(xiàn) EventListener 接口的對(duì)象, 或 一個(gè)函數(shù). 兩者實(shí)質(zhì)都是用來接收并處理觸發(fā)的事件.

options 可選

主要跟 listener 相關(guān)的

capture Boolean 表示該 listener 事件處理程序是否在捕獲階段被觸發(fā).

once Boolean 表示 listener 在添加之后最多只調(diào)用一次。如果是 true, listener 會(huì)在其被調(diào)用之后自動(dòng)移除。

passive: Boolean, 設(shè)置為true時(shí), 表示 listener 永遠(yuǎn)不會(huì)調(diào)用 preventDefault(). 如果 listener 仍然調(diào)用了這個(gè)函數(shù), 客戶端將會(huì)忽略它并拋出一個(gè)控制臺(tái)警告.

useCapture 可選

默認(rèn)值: false 表示在冒泡階段調(diào)用事件處理函數(shù).

小提示:

從參數(shù)簽名來看 optionsuseCapture 是不能同時(shí)配置, 這就是為什么 options 中會(huì)提供 capture 的原因. 這樣其實(shí)帶來另外一個(gè)好處, 可以更精確控制到每一個(gè)事件處理程序的觸發(fā)時(shí)機(jī)

先通過一個(gè)簡(jiǎn)單的示例來把上面知識(shí)點(diǎn)應(yīng)用一下,示例如下:

    

    

控制臺(tái)依次輸出:

    // 第一次點(diǎn)擊時(shí)
    "one handle"
    "two handle"
    "capture handle"
    "once handle"
    "window"

    // 第二次點(diǎn)擊時(shí)
    "one handle"
    "two handle"
    "capture handle"
    "window"

從輸出來看:

默認(rèn)是在冒泡階段來觸發(fā)事件處理程序 (listener); 需要捕獲階段攔截可以通過把 useCapture 改為 false.

使用DOM2級(jí) 默認(rèn)支持針對(duì)同一個(gè)事件類型添加多個(gè)處理程序. DOM0 級(jí) 不支持的.

事件觸發(fā)的順序按照添加順序執(zhí)行.

在講述語法時(shí), listener 可以是一個(gè)實(shí)現(xiàn) EventListener 接口的對(duì)象. 上面指定 listener 時(shí)我們可以使用如下方式:

    
    

一般推薦使用前者;

事件處理程序執(zhí)行的作用域
事件處理程序中 this 指向當(dāng)前對(duì)象(input)
    
    

控制臺(tái)輸出:

    "ClickMe"

移除事件處理程序
移除事件處理程序通過 removeListener 方法. 從語法來看, 傳入?yún)?shù)與添加時(shí)傳入的參數(shù)一樣, 也就是說事件處理程序(函數(shù))就不能為匿名函數(shù), 否則無法移除

錯(cuò)誤的使用方式:

    
    

控制臺(tái)輸出:

    "handleListener"

正確使用方式:

    
    

總結(jié):

指定事件類型時(shí),使用 click 而不是 onclick (click類型為例)

允許支持同一個(gè)事件名添加多個(gè)處理程序, 執(zhí)行順序?yàn)樘砑禹樞?

事件處理程序依附的對(duì)象, 作為處理函數(shù)執(zhí)行時(shí)的作用域.

移除事件處理程序時(shí), 不能使用匿名函數(shù).

兼容性:

IE9、Firefox、Safari、Chrome和 Opera 支持DOM2級(jí)事件處理程序

從兼容性來看,那么在IE中有沒有類似 addEventListener 和 removeEventListener 事件處理程序?

IE 中添加事件處理程序

IE實(shí)現(xiàn)了類似 DOM 中類似的兩個(gè)方式: attachEvent(), detachEvent(). 這兩個(gè)方法默認(rèn)接收兩個(gè)參數(shù).

語法格式(Non-standard):

    attachEvent(type, listener)
    detachEvent(tyoe, listener)

先來看個(gè)具體示例(IE中運(yùn)行):

    
    
    

控制臺(tái)輸出結(jié)果:

    // 點(diǎn)擊 "移除事件處理程序按鈕之前"
    "handleListener"
    "undefined"

    // 點(diǎn)擊之后, 再執(zhí)行沒有輸出(事件處理程序被移除)

注意:

事件類型名稱(type) 和 DOM0級(jí)一樣需要指定完整屬性名 onclick

移除事件處理程序時(shí), 傳入?yún)?shù)必須一樣

attachEvent 和 detachEvent 不支持捕獲, 也就是說在被添加到冒泡階段

事件處理程序在全局作用域中執(zhí)行

兼容

attachEvent 和 detachEvent 只能 IE10以及一下版本中使用.
IE事件處理程序與DOM0級(jí)的區(qū)別

在IE中使用 attachEvent detachEvent, 與 DOM0級(jí)不同的地方在于事件處理程序執(zhí)行時(shí)作用域不一樣. 前面講到過DOM0和 DOM2事件處理程序都會(huì)在所屬元素的作用域內(nèi)運(yùn)行; 從上面 this.id 打印結(jié)果來看, attachEvent 在全局作用域(window)中運(yùn)行.

到目前為止,把添加事件處理程序方式都一一列舉完. 具體引用那種可以根據(jù)實(shí)際需求選擇.

Event 對(duì)象常見應(yīng)用
是伴隨著事件執(zhí)行過程中的一個(gè)產(chǎn)物, 這個(gè)稱之為 event (事件對(duì)象). 該事件對(duì)象中包含很多跟事件以及用戶相關(guān)的內(nèi)容(例如: 事件類型、事件對(duì)象、用戶點(diǎn)擊位置、移動(dòng)位置等等)

下面羅列下 event object 包含常用屬性和方法:

名稱 描述 返回值
type 指定的事件名稱(例如 click, mouseout) string
target 表示要觸發(fā)事件的元素 HTMLElement
currentTarget 事件處理程序調(diào)用時(shí)的元素 HTMLElement
eventPhase 事件當(dāng)前處于事件的那個(gè)階段; 1 捕獲 2 事件目標(biāo) 3 冒泡階段 number
bubbles 表示當(dāng)前事件對(duì)象是否會(huì)向 DOM 樹上層元素冒泡 boolean
cancelable 事件的 cancelable 屬性表明該事件是否可以被取消默認(rèn)行為, 如果該事件可以用 preventDefault() 可以阻止與事件關(guān)聯(lián)的默認(rèn)行為,則返回 true,否則為 false boolean
timeStamp 返回事件發(fā)生時(shí)的時(shí)間戳. string
stopPropagation() 阻止捕獲和冒泡階段中當(dāng)前事件的進(jìn)一步傳播 如果 bubbles為ture可以使用 void
stopImmediatePropagation() 阻止事件冒泡并且阻止相同事件的其他偵聽器被調(diào)用 DOM3級(jí)中添加 void
preventDefault() 阻止事件默認(rèn)行為,事件依然會(huì)傳播除非遇到 stopPropogation 或 stopImmediatePropogation 如果 cancelable為turu則可以使用這個(gè)方法 void
defaultPrevented 返回一個(gè)布爾值,表明當(dāng)前事件是否調(diào)用了 event.preventDefault()方法 DOM3級(jí)中添加 boolean
如何來獲取事件對(duì)象

回顧前面講解添加事件處理程序(HTML事件處理程序、DOM0 、 DOM2) 分別看怎么來獲取

HTML事件處理程序時(shí):

    
    
    
    

可以通過這兩種方式來獲取事件對(duì)象

DOM0 和 DOM2

    
    

可以通過參數(shù)的方式來獲取, 這是推薦的獲取方式. 除了上述幾種方式外, 其實(shí)可以通過 window.event 來獲取表示當(dāng)前正觸發(fā)的事件對(duì)象, 不過這種方式不是標(biāo)準(zhǔn)(IE), 所以不推薦使用.

event 屬性和方法使用 target 和 currentTarget

引用前面的示例, 講述下 targetcurrentTarget

    

控制臺(tái)輸出:

    true
    true

結(jié)合前面對(duì)屬性描述, event.target 表示當(dāng)前事件觸發(fā)的對(duì)象. event.currentTarget 表示當(dāng)前事件處理程序執(zhí)行時(shí)的對(duì)象(上下文). 從打印結(jié)果來看,當(dāng)事件處理程序直接綁定目標(biāo)元素上時(shí),這兩者相同的.

什么時(shí)候不一樣咧?

    
    true
    false

符合預(yù)期, 上面代碼中把事件處理程序綁定在了 div#container 元素上, 這時(shí) currentTarget 是當(dāng)前的事件處理程序綁定的對(duì)象.

type

type 用于獲取當(dāng)前事件類型之外, 可以作如下用途, 當(dāng)希望在同一個(gè)事件處理程序中處理多個(gè)不同事件類型時(shí), 如下:

   
cancelable、preventDefault() 、 defaultPrevented

具體上個(gè)介紹可以參照前面的表格里面描述, 為什么把這三個(gè)結(jié)合在一塊, 彼此間是有關(guān)聯(lián)的.
先來看看具體示例:

    

控制臺(tái)輸出:

    true // 表示可以被阻止
    true // 表示調(diào)用 preventDefault() 

什么情況下會(huì)有 event.cancelable 返回 false ? 現(xiàn)有 focus、blur、
focusin、focusout 等不允許阻止, 或一些自定義的事件

    

控制臺(tái)輸出:

    false // 表示可以被阻止
    false // 表示調(diào)用 preventDefault() 
bubbles、stopPropagation()、stopImmediatePropagation()

具體上個(gè)介紹可以參照前面的表格里面描述, 為什么把這三個(gè)結(jié)合在一塊, 彼此間是有關(guān)聯(lián)的.
先來看看具體示例:

    

控制臺(tái)輸出:

    "handleOne" 
    true
    "handleTwo"

從輸出結(jié)果來看, event.stopPropagation() 只會(huì)阻止事件冒泡, 并不會(huì)阻止同類型多個(gè)事件處理程序的執(zhí)行.

再來看看 stopImmediatePropagation() 修改如下:

    

控制臺(tái)輸出:

    "handleOne" 
    true

event.stopImmediatePropagation() 阻止事件冒泡的同時(shí)當(dāng)前事件類型下其它事件處理程序的執(zhí)行. 如果 handleOne 中調(diào)用 stopImmediatePropagation, 那么 handleTwo就不會(huì)再執(zhí)行.

eventPhase

當(dāng)前事件處于那個(gè)階段

      // PhaseType
    CAPTURING_PHASE                = 1;  // 捕獲
    AT_TARGET                      = 2;  // 事件目標(biāo)
    BUBBLING_PHASE                 = 3;  // 冒泡階段 

先來看看簡(jiǎn)單示例:

    

前面講解都是DOM標(biāo)準(zhǔn),也就是所有瀏覽器廠商都支持的, 那么來看看 IE9 以下版本中會(huì)不會(huì)有什么不一樣.

IE中事件對(duì)象

我們也從添加事件處理程序的維度出發(fā), 看看有什么不一樣.

HTML事件處理程序
    

正常彈出 click, 這與前面說到的一樣.

DOM0

以前面的示例來演示:

    
    

控制條輸出:

    undefined
    [object Object]

測(cè)試環(huán)境: IE8以及一下的版本

在 DOM0 級(jí)事件處理程序中, 事件對(duì)象添加在 window 上的屬性 event

attachEvent

引用上面代碼, 使用 attachEvent 來添加事件,并獲取 event

    
    var target = document.getElementById("button");
    target.attachEvent("onclick", function(e){
        console.log(e);
    })
事件對(duì)象相關(guān)的屬性
名稱 描述 返回值
type 指定的事件名稱(如 click, mouseout) string
srcElement 表示要觸發(fā)事件的元素(與DOM中 target) HTMLElement
returnValue 默認(rèn)值為 true, 但將其設(shè)置為 false, 就可以取消事件的默認(rèn)行為(與DOM中 preventDefault()) Boolean
cancelBubble 默認(rèn)值為 false, 但將其設(shè)置為 ture. 就取消冒泡行為(與DOM中的 stopPropagation()) Boolean

看看具體示例:

    
    

當(dāng)點(diǎn)擊按鈕時(shí), 輸出結(jié)果:

    "true"

當(dāng)點(diǎn)擊超鏈接時(shí), 輸出結(jié)果:

    "container"

從點(diǎn)擊超鏈接來看, e.returnValue 只會(huì)阻止默認(rèn)行為, 事件對(duì)象依然進(jìn)行會(huì)冒泡.

事件、目標(biāo)、事件冒泡、事件默認(rèn)行為獲取方式-匯總
添加事件程序方式 語法 兼容
HTML事件處理程序 < element onclick="alert(event)" > All
DOM0 element.onclick = function(event){} All
DOM2 addEventListener IE9+,Chrome,Firfox,Safari,360
IE attachEvent IE11<
獲取事件對(duì)象 方式 例子
HTML事件處理程序 event 變量 < element onclick="alert(event)" >
DOM0 事件處理程序參數(shù) 、IE9以下通過 windiw.event function(event){}、window.event
DOM2 事件處理程序參數(shù) function(event){}
IE 事件處理程序參數(shù) function(event){}
獲取目標(biāo)對(duì)象方式 屬性名 兼容
標(biāo)準(zhǔn) target IE9+,Chrome,Firfox,Safari,360
IE版本 srcElement IE9<
阻止事件冒泡 屬性或方法 兼容
標(biāo)準(zhǔn) stopPropagation()、stopImmediatePropagation() IE9+,Chrome,Firfox,Safari,360
IE版本 cancelBubble IE9<
阻止默認(rèn)行為 屬性或方法 兼容
標(biāo)準(zhǔn) preventDefault() IE9+,Chrome,Firfox,Safari,360
IE版本 returnValue IE9<
事件的操作類(兼容所有版本)
    var EventUtil = {

        addHandler: function(element, type, handler) {
            if(element.addEventListener) {
                element.addEventListener(type, handler);
            }else if(element.attachEvent){
                element.attachEvent("on" + type, handler);
            }else {
                element["on" + type] =  handler;
            }
        },
        removeHandler: function(element, type, handler){
            if(element.addEventListener) {
                element.removeEventListener(type, handler);
            }else if(element.attachEvent){
                element.detachEvent("on" + type, handler);
            }else {
                element["on" + type] =  null;
            }
        },

        getEvent: function(event){
            return event? event : window.event;
        },
        getTarget: function(event){
            return event.target ? event.target:event.srcElement;
        },

        stopPropagation: function(event){
            if(event.stopPropagation) {
                event.stopPropagation();
            }else {
                event.cancelBubble = true;
            }
        },
        preventDefault: function(event){
            if(event.preventDefault) {
                event.preventDefault();
            }else {
                event.returnValue = false;
            }
        }
    }

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105188.html

相關(guān)文章

  • DOM知識(shí)整理

    摘要:繼承接口對(duì)象不僅實(shí)現(xiàn)了接口,也實(shí)現(xiàn)了接口,用來標(biāo)識(shí)當(dāng)前窗口內(nèi)的文檔節(jié)點(diǎn)。繼承接口描述了所有相同種類的元素所普遍具有的方法和屬性。 由于工作中一直在用框架來解決問題,在平時(shí)對(duì)dom的關(guān)注也比較少(特別像angular這種自己封裝了一層視圖層的框架,并不建議直接操作DOM),所以dom相關(guān)的知識(shí)也忘的差不多了,這次做公司產(chǎn)品的官網(wǎng),沒有太多的交互和功能,直接用了原生js,正好借此整理一下遺...

    huayeluoliuhen 評(píng)論0 收藏0
  • 整理DOM事件相關(guān)識(shí)點(diǎn)

    摘要:事件相關(guān)內(nèi)容當(dāng)用戶與瀏覽器發(fā)生的一些交互時(shí)如果希望去獲得用戶行為就需要借助事件來完成事件部分內(nèi)容在中重要性不言而喻羅列需要了解與事件相關(guān)的知識(shí)如下這也是面試中遇到的問題事件的級(jí)別事件模型事件流事件處理程序描述事件捕獲冒泡的具體流程對(duì)象常見的 DOM事件相關(guān)內(nèi)容 當(dāng)用戶與瀏覽器發(fā)生的一些交互時(shí), 如果希望去獲得用戶行為, 就需要借助事件來完成. 事件部分內(nèi)容在 JS中重要性不言而喻. ...

    shenhualong 評(píng)論0 收藏0
  • 前端面試之路二(javaScript基礎(chǔ)整理)

    摘要:在標(biāo)簽中添加屬性,本質(zhì)上是跟在標(biāo)簽里面寫屬性時(shí)一樣的,所以屬性值最終都會(huì)編譯為字符串類型。這個(gè)節(jié)點(diǎn)包括很多,比如,以及一些方法等方法。一個(gè)對(duì)象有很多,該集合名字為,里面有其他以及,里面有很多。 一、變量類型和計(jì)算 JS中使用typeof能得到哪些類型 變量類型 值類型:變量本身就是含有賦予給它的數(shù)值的,它的變量本身及保存的數(shù)據(jù)都存儲(chǔ)在棧的內(nèi)存塊當(dāng)中 引用類型:引用類型當(dāng)然是分配到...

    AbnerMing 評(píng)論0 收藏0
  • 前端開發(fā)識(shí)點(diǎn)整理

    摘要:前言本文主要是有關(guān)前端方面知識(shí)按照目前的認(rèn)知進(jìn)行的收集歸類概括和整理,涵蓋前端理論與前端實(shí)踐兩方面。 前言:本文主要是有關(guān)前端方面知識(shí)按照 XX 目前的認(rèn)知進(jìn)行的收集、歸類、概括和整理,涵蓋『前端理論』與『前端實(shí)踐』兩方面。本文會(huì)告訴你前端需要了解的知識(shí)大致有什么,看上去有很多,但具體你要學(xué)什么,還是要 follow your heart & follow your BOSS。 初衷...

    Blackjun 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<