国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端小知識--JavaScript事件流

Taste / 379人閱讀

摘要:事件事件指可以被偵測到的行為。事件通常與函數(shù)配合使用,當(dāng)事件發(fā)生時(shí)函數(shù)才會執(zhí)行。兩家公司對于事件流出現(xiàn)了截然相反的定義。級事件規(guī)定的事件流包括三個(gè)階段事件捕獲階段處于目標(biāo)階段事件冒泡階段。我們又把事件處理程序稱為事件偵聽器。

JavaScript事件流 0.DOM級別與DOM事件
首先在介紹DOM事件之前我們先來認(rèn)識下DOM的不同級別。針對不同級別的DOM,我們的DOM事件處理方式也是不一樣的。
DOM級別一共可以分為4個(gè)級別:DOM0級,DOM1級,DOM2級和DOM3級,
而DOM事件分為3個(gè)級別:DOM0級事件處理,DOM2級事件處理和DOM3級事件處理。

如下圖所示:

其中1級DOM標(biāo)準(zhǔn)中并沒有定義事件相關(guān)的內(nèi)容,所以沒有所謂的1級DOM事件模型。

1.事件
事件指可以被 JavaScript 偵測到的行為。即鼠標(biāo)點(diǎn)擊、頁面或圖像載入、鼠標(biāo)懸浮于頁面的某個(gè)熱點(diǎn)之上、在表單中選取輸入框、確認(rèn)表單、鍵盤按鍵等操作。事件通常與函數(shù)配合使用,當(dāng)事件發(fā)生時(shí)函數(shù)才會執(zhí)行。
事件名稱:click/mouseover/blur("不帶on")

響應(yīng)某個(gè)事件的函數(shù)就是事件處理程序(事件偵聽器)。
事件處理程序函數(shù)名稱:onclick/onmouseove/onblur

例子代碼--點(diǎn)擊事件觸發(fā)alert函數(shù)

更多事件類別請參考w3c中關(guān)于事件的詳細(xì)類別。
JavaScript 事件
JavaScript 事件參考手冊

2.事件流
事件流指從頁面中接收事件的順序,也可理解為事件在頁面中傳播的順序。

一點(diǎn)背景:
早期的IE事件傳播方向?yàn)橛缮现料拢磸膁ocument逐級向下傳播到目標(biāo)元素;
而Netscape公司的Netscape Navigator則是朝相反的方向傳播,也就是從目標(biāo)元素開始向上逐級傳播最終至window。 兩家公司對于事件流出現(xiàn)了截然相反的定義。

后來ECMAScript在DOM2中對事件流進(jìn)行了進(jìn)一步規(guī)范,基本上就是上述二者的結(jié)合。
當(dāng)事件發(fā)生時(shí),最先得到通知的是window,然后是document,由上至下逐級依次而入,直到真正觸發(fā)事件的那個(gè)元素(目標(biāo)元素)為止,這個(gè)過程就是捕獲。
接下來,事件會從目標(biāo)元素開始起泡,由下至上逐級依次傳播,直到window對象為止,這個(gè)過程就是冒泡。
所以捕獲比冒泡先執(zhí)行。
其中DOM3級事件在DOM2的基礎(chǔ)之上添加了更多的事件類型。

DOM2級事件規(guī)定的事件流包括三個(gè)階段:
(1)事件捕獲階段(2)處于目標(biāo)階段(3)事件冒泡階段。
下面圖片來自:https://www.w3.org/TR/DOM-Lev...

我們寫一個(gè)例子:如下圖,中間白色區(qū)域的盒子分別為box1,box2...box6,包含控制按鈕設(shè)置我們的事件

    

點(diǎn)擊按鈕設(shè)置類型后再點(diǎn)擊中心

點(diǎn)擊

大概流程圖如下:

演示效果如圖:

例子源碼
參考鏈接————小俠同學(xué)

3.事件處理程序
前面我們已經(jīng)說到了,事件處理程序就是響應(yīng)某個(gè)事件的函數(shù),簡單地來說,就是函數(shù)。我們又把事件處理程序稱為事件偵聽器。事件處理程序是以"on"開頭的,比如點(diǎn)擊事件的處理程序是"onclick",事件處理程序大概有以下5種。

1.HTML事件處理程序

2.DOM0級事件處理程序

3.DOM2級事件處理程序

4.IE事件處理程序

5.跨瀏覽器的事件處理程序

3.1 HTML事件處理程序

像我們的第一個(gè)例子,就是HTML事件處理程序,它是寫在html里面的,是全局作用域:

例子代碼--點(diǎn)擊事件觸發(fā)alert函數(shù)

當(dāng)我們需要使用一個(gè)復(fù)雜的函數(shù)時(shí),將js代碼寫在這里面,顯然很不合適,所以有了下面這種寫法:

例子代碼--點(diǎn)擊事件觸發(fā)doSomething()函數(shù),這個(gè)函數(shù)寫在多帶帶的js文件或

可以看到button.onclick這種形式,這里事件處理程序作為了btn對象的方法,是局部作用域。
所以我們可以用

btn.onclick = null;來刪除指定的事件處理程序。

如果我們嘗試給事件添加兩個(gè)事件,如:


 

輸出,hello again,很明顯,第一個(gè)事件函數(shù)被第二個(gè)事件函數(shù)給覆蓋掉了,所以,DOM0級事件處理程序不能添加多個(gè),也不能控制事件流到底是捕獲還是冒泡。

3.3 DOM2級事件處理程序(不支持IE)

進(jìn)一步規(guī)范之后,有了DOM2級事件處理程序,其中定義了兩個(gè)方法:
addEventListener() ---添加事件偵聽器
removeEventListener() ---刪除事件偵聽器
具體用法看
1.https://developer.mozilla.org...
2.https://developer.mozilla.org...
函數(shù)均有3個(gè)參數(shù),
第一個(gè)參數(shù)是要處理的事件名(不帶on前綴的才是事件名)
第二個(gè)參數(shù)是作為事件處理程序的函數(shù)
第三個(gè)參數(shù)是一個(gè)boolean值,默認(rèn)false表示使用冒泡機(jī)制,true表示捕獲機(jī)制。


 

這時(shí)候兩個(gè)事件處理程序都能夠成功觸發(fā),說明可以綁定多個(gè)事件處理程序,但是注意,如果定義了一摸一樣時(shí)監(jiān)聽方法,是會發(fā)生覆蓋的,即同樣的事件和事件流機(jī)制下相同方法只會觸發(fā)一次,比如:


 

removeEventListener()的方法幾乎和添加時(shí)用法一摸一樣:


 

這樣的話,事件處理程序只會執(zhí)行一次。
但是要注意,如果同一個(gè)監(jiān)聽事件分別為“事件捕獲”和“事件冒泡”注冊了一次,一共兩次,這兩次事件需要分別移除。兩者不會互相干擾。
這時(shí)候的this指向該元素的引用。
這里事件觸發(fā)的順序是添加的順序。

3.4 IE事件處理程序

對于 Internet Explorer 來說,在IE 9之前,你必須使用 attachEvent 而不是使用標(biāo)準(zhǔn)方法 addEventListener。
IE事件處理程序中有類似與DOM2級事件處理程序的兩個(gè)方法:
1.attachEvent()
2.detachEvent()
它們都接收兩個(gè)參數(shù):
1.事件處理程序名稱。如onclick、onmouseover,注意:這里不是事件,而是事件處理程序的名稱,所以有on。
2.事件處理程序函數(shù)。
之所以沒有和DOM2級事件處理程序中類似的第三個(gè)參數(shù),是因?yàn)镮E8及更早版本只支持冒泡事件流。
removeEventListener()的方法幾乎和添加時(shí)用法一摸一樣:


 

這里事件觸發(fā)的順序不是添加的順序而是添加順序的相反順序。
使用 attachEvent 方法有個(gè)缺點(diǎn),this 的值會變成 window 對象的引用而不是觸發(fā)事件的元素。

3.5 跨瀏覽器的事件處理程序
為了兼容IE瀏覽器和標(biāo)準(zhǔn)的瀏覽器,我們需要編寫通用的方法來處理:
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 if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        }
    }
};

這一部分需要創(chuàng)建兩個(gè)方法:
addHandler() --這個(gè)方法職責(zé)是視情況來使用DOM0級、DOM2級、IE事件處理程序來添加事件。
removeHandler()--這個(gè)方法就是移除使用addHandler添加的事件。
這兩個(gè)方法接收相同的三個(gè)參數(shù):
1.要操作的元素--通過dom方法獲取
2.事件名稱--注意:沒有on,如"click"、"mouseover"
3.事件處理程序函數(shù)--對應(yīng)的函數(shù)

使用:


 
4.事件對象
事件對象是用來記錄一些事件發(fā)生時(shí)的相關(guān)信息的對象,但事件對象只有事件發(fā)生時(shí)才會產(chǎn)生,并且只能是事件處理函數(shù)內(nèi)部訪問,在所有事件處理函數(shù)運(yùn)行結(jié)束后,事件對象就被銷毀!

屬性和方法如圖,詳細(xì)請查看以下鏈接:
1.HTML DOM Event 對象:http://www.w3school.com.cn/js...
2.詳細(xì)介紹請查看:http://www.jb51.net/article/9...

4.1 屬性

下面是一個(gè)例子:


 

在這個(gè)例子里,我們用到了currentTargeteventPhase 屬性。

4.2 方法

Event對象主要有以下兩個(gè)方法,用于處理事件的傳播(冒泡、捕獲)和事件的取消。
stopPropagation()——冒泡機(jī)制下,阻止事件的進(jìn)一步往上冒泡

    var btn1=document.getElementById("btn1");
    var content=document.getElementById("content");
    btn1.addEventListener("click",function(event){
        alert("btn1");
        event.stopPropagation();
    },false);
    content.addEventListener("click",function(){
        alert("content");
    },false);
    //這里會輸出btn1,阻止了向content的冒泡

preventDefault()——用于取消事件的默認(rèn)操作,比如鏈接的跳轉(zhuǎn)或者表單的提交,主要是用來阻止標(biāo)簽的默認(rèn)行為

禁止跳轉(zhuǎn)
var go = document.getElementById("go");
function goFn(event) {
 event.preventDefault();
// 不會跳轉(zhuǎn)
}
go.addEventListener("click", goFn, false);
4.3 兼容性

當(dāng)然,事件對象也存在一定的兼容性問題,在IE8及以前本版之中,通過設(shè)置屬性注冊事件處理程序時(shí),調(diào)用的時(shí)候并未傳遞事件對象,需要通過全局對象window.event來獲取。解決方法如下:

function getEvent(event) {
 event = event || window.event;
}

在IE瀏覽器上面是event事件是沒有preventDefault()這個(gè)屬性的,所以在IE上,我們需要設(shè)置的屬性是returnValue

window.event.returnValue=false

stopPropagation()也是,所以需要設(shè)置cancelBubble,cancelBubble是IE事件對象的一個(gè)屬性,設(shè)置這個(gè)屬性為true能阻止事件進(jìn)一步傳播。

event.cancelBubble=true
5.事件委托
事件委托就是利用事件冒泡,只指定一個(gè)事件處理程序,就可以管理某一類型的所有事件。

例子說明,我們?yōu)閡l添加新的li,其中對li標(biāo)簽元素綁定了click事件,但是發(fā)現(xiàn),后增加的元素沒有辦法觸發(fā)我們的click事件。

    
    
  • 1
  • 2
  • 3

這是因?yàn)槿绻录婕暗礁翲TML節(jié)點(diǎn)或者添加HTML節(jié)點(diǎn)時(shí),新添加的節(jié)點(diǎn)無法綁定事件,更新的節(jié)點(diǎn)也是無法綁定事件,表現(xiàn)的行為是無法觸發(fā)事件。
其中一種解決方法是,添加子節(jié)點(diǎn)的時(shí)候,再次為其添加監(jiān)聽事件

    
    
  • 1
  • 2
  • 3

這也是問題所在:
 1.首先我們多次操作DOM獲取元素,這樣勢必會降低瀏覽器處理性能
 2.事件不具有繼承性,如果我們動態(tài)在頁面中添加了一個(gè)元素,那么還需要重新走一遍上述程序?yàn)槠涮砑颖O(jiān)聽事件

那么有沒有更好的方法呢?根據(jù)事件的冒泡原理,我們還可以實(shí)現(xiàn)另外一個(gè)很重要的功能:事件委托

我們只監(jiān)聽最外層的元素,然后在事件函數(shù)中根據(jù)事件來源進(jìn)行不同的事件處理。這樣,我們添加事件監(jiān)聽時(shí)只需要操作一個(gè)元素,極大的降低了DOM訪問,并且不用再給新增的元素添加監(jiān)聽事件了,因?yàn)樵氐氖录芭莸阶钔鈱樱晃覀兘孬@。

    
    
  • 1
  • 2
  • 3

這里用父級ul做事件處理,當(dāng)li被點(diǎn)擊時(shí),由于冒泡原理,事件就會冒泡到ul上,因?yàn)閡l上有點(diǎn)擊事件,所以事件就會觸發(fā),當(dāng)然,這里當(dāng)點(diǎn)擊ul的時(shí)候,也是會觸發(fā)的,所以要判斷點(diǎn)擊的對象到底是不是li標(biāo)簽元素。

Event對象提供了一個(gè)屬性叫target,可以返回事件的目標(biāo)節(jié)點(diǎn),我們成為事件源,也就是說,target就可以表示為當(dāng)前的事件操作的dom,但是不是真正操作dom,當(dāng)然,這個(gè)是有兼容性的,標(biāo)準(zhǔn)瀏覽器用ev.target,IE瀏覽器用event.srcElement,此時(shí)只是獲取了當(dāng)前節(jié)點(diǎn)的位置,并不知道是什么節(jié)點(diǎn)名稱,這里我們用nodeName來獲取具體是什么標(biāo)簽名,這個(gè)返回的是一個(gè)大寫的,我們需要轉(zhuǎn)成小寫再做比較(習(xí)慣問題)。

這樣,我們就實(shí)現(xiàn)了我們的事件委托,當(dāng)然,不是所有的事件都是可以委托的。
適合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。

當(dāng)用事件委托的時(shí)候,根本就不需要去遍歷元素的子節(jié)點(diǎn),只需要給父級元素添加事件就好了,新增加的節(jié)點(diǎn)也可以觸發(fā)事件效果。

參考:
1.http://www.cnblogs.com/souven...
2.https://www.cnblogs.com/st-le...
3.https://segmentfault.com/a/11...
4.http://www.jb51.net/article/9...
5.http://www.w3school.com.cn/js...
6.http://www.jb51.net/article/8...
7.http://www.jb51.net/article/9...

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/107424.html

相關(guān)文章

  • 前端基礎(chǔ) - 事件入門

    摘要:及更早版本不支持事件流。綁定作用域其他的地方,就跟類似,都可以綁定多個(gè)事件處理程序,要刪除只能調(diào)用,并且不能使用匿名函數(shù)的形式。 事件知識快速入門 事件是前端開發(fā)必備的知識,我通過閱讀《JavaScript高級程序設(shè)計(jì)》,梳理了一下整個(gè)事件的知識體系,下面一起來學(xué)習(xí)吧。 1. 背景知識 跟所有開發(fā)UI的思路一樣,JavaScript與HTML之間通過事件來進(jìn)行交互。事件,就是文檔或?yàn)g覽...

    bbbbbb 評論0 收藏0
  • 認(rèn)識node核心模塊--從Buffer、Stream到fs

    摘要:端輸入數(shù)據(jù)到端,對就是輸入流,得到的對象就是可讀流對就是輸出端得到的對象是可寫流。在中,這四種流都是的實(shí)例,它們都有事件,可讀流具有監(jiān)聽數(shù)據(jù)到來的事件等,可寫流則具有監(jiān)聽數(shù)據(jù)已傳給低層系統(tǒng)的事件等,和都同時(shí)實(shí)現(xiàn)了和的事件和接口。 原文地址在我的博客 node中的Buffer和Stream會給剛接觸Node的前端工程師們帶來困惑,原因是前端并沒有類似概念(or 有我們也沒意識到)。然而,...

    TANKING 評論0 收藏0
  • 【連載】前端個(gè)人文章整理-從基礎(chǔ)到入門

    摘要:個(gè)人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開始萌生寫文章的想法,到著手...

    madthumb 評論0 收藏0
  • 前端事件綁定知識點(diǎn)(面試常考)

    摘要:事件通常與函數(shù)配合使用,當(dāng)事件發(fā)生時(shí)函數(shù)才會執(zhí)行。的事件流是事件捕獲流,事件由根元素獲取并沿樹向下分發(fā)。通過添加事件,只能用刪除此事件。這主要得益于瀏覽器的事件冒泡機(jī)制。 簡介 事件是可以被 JavaScript 偵測到的行為。 網(wǎng)頁中的每個(gè)元素都可以產(chǎn)生某些可以觸發(fā) JavaScript 函數(shù)或程序的事件。 事件通常與函數(shù)配合使用,當(dāng)事件發(fā)生時(shí)函數(shù)才會執(zhí)行。 執(zhí)行JS 事件的方式: ...

    liujs 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<