javascript----事件


事件處理程序在應(yīng)用中是必不可少的,雖然現(xiàn)在很多框架都有自己實現(xiàn)事件處理方法,但是熟知原生才能讓我們應(yīng)對各種各樣的需求并且實現(xiàn)自己的想法


事件流

這個是很基本很基本的概念了
DOM2級事件規(guī)定的事件流包括三個階段:
①事件捕獲階段
②處于目標(biāo)階段
③冒泡階段
并且明確要求捕獲階段不會涉及事件目標(biāo)


事件處理程序

這里主要講DOM2級事件處理程序,HTML事件處理程序和DOM0級事件處理程序現(xiàn)在幾乎很少接觸,故跳過

DOM2級事件處理程序

addEventListener()
接收三個參數(shù):①要處理的事件名②事件處理程序③布爾值(true表示捕獲階段調(diào)用時間處理程序(建議),false表示冒泡階段)
removeEventListenser()
接收的參數(shù)與addEventListener一樣,需要注意的是,通過addEventListener()添加的匿名函數(shù)將無法通過removeEventListener()移除

IE事件處理程序

addEventListener在IE8及更早版本都不給予支持,但有類似的兩個方法:attachEvent()detachEvent(),同樣接收事件處理程序名稱和事件處理程序函數(shù)作為參數(shù),默認在冒泡階段調(diào)用
注意:
①這里的時間處理程序名稱沒有on前綴
②這里的時間處理程序會在全局作用域中運行,故this等于window

跨瀏覽器的事件處理程序

var EventUtil = {
    addHandler:function(element,type,handler){
        if(element.addEventListener){
            element.addEventListener(type,handler,false);
        }else if(elment.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;
        }
    }
}

事件對象

事件對象包含著所有與時間有關(guān)的信息,包括導(dǎo)致事件的元素、事件的類型以及其他與特定時間相關(guān)的信息.事件對象又分為DOM事件對象和IE事件對象,下面將分開總結(jié)

DOM中的事件對象

兼容DOM的瀏覽器會將一個event對象傳入到事件處理程序中,event對象包含與創(chuàng)建它的特定事件有關(guān)的屬性和方法,不同事件類型不一樣,不過所有事件都有下列共同的屬性和方法

  • bubbles 布爾值 表明事件是否冒泡
  • cancelable 布爾值 表明是否可以取消事件的默認行為
  • currentTarget 節(jié)點 其事件處理程序當(dāng)前正在處理事件的那個元素
  • defaultPrevented 布爾值 是否被阻止了默認操作
  • detail Integer 與事件相關(guān)的細節(jié)
  • eventPhase Integer 調(diào)用事件處理程序的階段:1->捕獲 2->處于目標(biāo) 3->冒泡
  • preventDefault() 取消事件的默認行為
  • stopImmediatePropagation() 取消事件的進一步捕獲或冒泡同時阻止任何事件處理程序被調(diào)用(DOM3)
  • stopPropagation() 取消事件的進一步捕獲或冒泡
  • target 節(jié)點 事件的目標(biāo)
  • trusted 布爾值 是否為瀏覽器生成的
  • type 被觸發(fā)的事件的類型
  • view 與事件關(guān)聯(lián)的抽象視圖

注意:在事件處理程序內(nèi)部,對象this始終等于currentTarget,即相應(yīng)事件的元素,而不一定是觸發(fā)事件的元素,而event.target則指向觸發(fā)事件的元素

IE中的事件對象

要訪問IE中的event對象的方式取決于指定事件處理程序的方法:
①使用DOM0級添加事件處理程序時,event對象作為window對象的一個屬性存在
②使用attachEvent()添加的事件處理程序,會有一次event傳入事件函數(shù)中
③通過HTML特性制定的事件處理程序,可以通過一個叫event的變量來訪問event對象

IE的event對象同樣包含與創(chuàng)建它的事件相關(guān)的屬性和方法,但所有事件對象都會包含下面所列的屬性和方法

  • cancelBubble 布爾值 默認false,設(shè)置為true可以取消事件冒泡
  • returnValue 布爾值 默認true,但將其設(shè)置為false可以取消事件的默認行為
  • srcElement 事件的目標(biāo),與DOM中的target屬性相同
  • type 被觸發(fā)的事件的類型

跨瀏覽器的事件對象

var EventUtil = {
    addHandler:function(element,type,handler){
        if(element.addEventListener){
            element.addEventListener(type,handler,false);
        }else if(elment.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;
        }
    },
    getEvent:function(event){
        return event? event: window.event;
    },
    getTarget:function(event){
        return event.target||event.srcElement;
    },
    preventDefault:function(event){
        if(event.preventDefault){
            event.preventDefault;
        }else{
            event.returnValue = false;
        }
    },
    stopPropagation:function(event){
        if(event.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble = true;
        }
    }
}

事件類型

UI事件

  • load

當(dāng)頁面完全加載后在window上觸發(fā),當(dāng)圖像加載完畢時在img元素上觸發(fā)等

注意:對于新圖像元素,只要設(shè)置了src屬性就會開始下載,但script和link只有在把相關(guān)元素添加到文檔后才會開始下載

  • unload

在文檔被完全卸載后觸發(fā),利用最多的情況是清除引用,以避免內(nèi)存泄漏

  • resize

當(dāng)瀏覽器窗口被調(diào)整到一個新的高度或?qū)挾葧r,就會觸發(fā)resize事件,建議在該事件的事件處理程序中不要加入大計算量的代碼,因為會被頻繁執(zhí)行,從而導(dǎo)致瀏覽器反應(yīng)變慢

  • scroll事件

發(fā)生滾動時觸發(fā),雖然在window對象上發(fā)生,但它實際表示的是頁面中相應(yīng)元素的變化,通常配合scrollLeft和scrollTop來使用

焦點事件

  • focus
  • blur

鼠標(biāo)與滾輪事件

鼠標(biāo)事件

  • click
  • dblclick
  • mousedown
  • mouseup
  • mouseenter 在鼠標(biāo)從元素外部首次移動到元素范圍之內(nèi)觸發(fā)
  • mouseleave 在位于元素上方的鼠標(biāo)光標(biāo)移動到元素范圍之外時觸發(fā)
  • mousemove 當(dāng)鼠標(biāo)指針在元素內(nèi)部移動時重復(fù)地觸發(fā)
  • mouseout 當(dāng)鼠標(biāo)指針位于一個元素上方,然后用戶將其移入另一個元素時觸發(fā),又移入的另一個元素可能位于前一個元素的外部,也可能是這個元素的子元素
  • mouseover 在鼠標(biāo)指針位于一個元素外部,然后用戶將其首次移入另一個元素邊界之內(nèi)觸發(fā)
  • mousewheel 當(dāng)用戶通過鼠標(biāo)滾輪與頁面交互、在垂直方向上滾動頁面都會觸發(fā)mousewheel事件

注意 除了mouseenter和mouseleave之外,所有鼠標(biāo)事件都會冒泡

鼠標(biāo)事件event特有屬性

  • 客戶區(qū)坐標(biāo)位置:
    通過event.clientX和event.clientY來獲取鼠標(biāo)光標(biāo)距離視口的位置
  • 頁面坐標(biāo)位置:
    通過event.pageX和event.pageY來獲取鼠標(biāo)光標(biāo)距離頁面的位置
  • 屏幕坐標(biāo)位置
    通過event.screenX和event.screenY來獲取鼠標(biāo)光標(biāo)距離屏幕的位置
  • 修改鍵
    鼠標(biāo)可能會配合修改鍵使用,可以通過event.shiftKey,event.ctrlKey,event.altKey,event.metaKey的布爾值來獲知對應(yīng)的修改鍵是否按下了,從而給予正確的反饋事件
  • 相關(guān)元素
    在發(fā)生mouseover和mouseout事件時,會涉及到更多的元素
    ①mouseover: 主目標(biāo)是獲得光標(biāo)的元素,相關(guān)元素是失去光標(biāo)的元素
    ②mouseout: 主目標(biāo)是失去光標(biāo)的元素,相關(guān)元素是獲得光標(biāo)的元素
    DOM中,event.relatedTarget表示相關(guān)元素
    IE8之前,前者用event.fromElement,后者用event.toElement來表示相關(guān)元素
  • 鼠標(biāo)按鈕
    對于mousedown和mouseup事件,其event對象存在一個button屬性,表示按下或釋放的按鈕,在DOM中,button屬性有以下值
    0表示主鼠標(biāo)按鈕
    1表示中間按鈕
    2表示次鼠標(biāo)按鈕
    在IE8及之前版本中也提供button屬性,不過屬性值與DOM有很大差異
    這里有跨瀏覽器方案:
    var EventUtil = {
  //省略了其他代碼
   getButton:function(event){
    if(document.implementation.hasFeature("MouseEvents","2.0")){
        return event.button
    }else{
        switch(event.button){
            case 0:
            case 1:
            case 3:
            case 5:
            case 7:
                return 0;
            case 2:
            case 6:
                return 2;
            case 4:
                return 1;
        }
    }
    },
     //省略了其他代碼
    };

鼠標(biāo)滾輪事件
mousewheel的event對象除包含鼠標(biāo)事件的所有標(biāo)準(zhǔn)信息外,還包含一個特殊的wheelDelta屬性(IE,Opera,Chrome,Safari), detail屬性(Firefox)
在wheelDelta
向前滾動:wheelDelta是120的倍數(shù)
向后滾動:wheelDelta是-120的倍數(shù)
在detail
向前滾動:detail的值是3的倍數(shù)
前后滾動:detail的值是-3的倍數(shù)
此處有跨瀏覽器方案:
var EventUtil = { //省略了其他代碼 getWheelDelta:function(event){ if(event.wheelDelta){ return(client.engine.opera&&client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta); }else{ return -event.detail * 40; } } }

鍵盤與文本事件

有三個鍵盤事件和一個文本事件

  • keydown: 當(dāng)用戶按下鍵盤上任意鍵時觸發(fā),按住不放則連續(xù)觸發(fā)
  • keypress: 當(dāng)用戶按下鍵盤上字符鍵時觸發(fā),按住不放則連續(xù)觸發(fā)
    (Safari3.1之前的版本在按下非字符鍵時也會觸發(fā)
  • keyup: 當(dāng)用戶釋放鍵盤上的鍵時觸發(fā)
  • textInput: 在文本插入文本框前會觸發(fā)textInput事件,用意是將文本顯示給用戶之前更容易攔截文本

鍵盤事件event特有屬性

  • 鍵碼
    在發(fā)生keydown和keyup事件時,event對象的keyCode屬性會包含一個代碼與對應(yīng)的按鍵對應(yīng)
  • 字符編碼
    發(fā)生keypress事件意味著按下的鍵會影響到屏幕中文本的顯示,因此在所有瀏覽器中,按下能夠插入或刪除字符的鍵都會觸發(fā)keypress事件

變動事件

  • DOMSubtreeModified:在DOM結(jié)構(gòu)中發(fā)生任何變化時觸發(fā)
  • DOMNodeInserted:在一個節(jié)點作為子節(jié)點被插入另一個節(jié)點時觸發(fā)
  • DOMNodeRemoved: 在節(jié)點從其父節(jié)點中被移除時觸發(fā)
  • DOMNodeInsertedIntoDocument:在一個節(jié)點被直接插入文檔或通過子樹間插入文檔之后觸發(fā)
  • DOMNodeRedmovedFromDocument:同理
  • DOMAttrModified:在特征被修改之后觸發(fā)
  • DOMCharacterDataModified:在文本節(jié)點的值發(fā)生變化時觸發(fā)

HTML5事件

  • contextmenu:單機鼠標(biāo)右擊事件
  • beforeunload:在瀏覽器卸載頁面之前觸發(fā)
  • DOMContentLoaded:在頁面中的一切都加載完畢時觸發(fā),在形成完整的DOM樹之后就會觸發(fā),不理會圖像、js文件等資源是否下載完畢
  • readystatechange
    這個事件的目的時提供與文檔或元素的加載狀態(tài)有關(guān)的信息,支持此事件的每個對象都有一個readyState屬性
  • pageshow和pagehide事件(Firfox opera)
  • hashchange:在URL的參數(shù)列表發(fā)生改變時觸發(fā)

設(shè)備事件(略)

觸摸與手勢事件

觸摸事件
  • touchstart:當(dāng)手指觸摸屏幕時觸發(fā)
  • touchumove:當(dāng)手指在屏幕上滑動時連續(xù)地觸發(fā)
  • touchend:當(dāng)手指從屏幕上移開時觸發(fā)
  • touchcancel:當(dāng)系統(tǒng)停止跟蹤觸摸時觸發(fā)
    除了常見的DOM屬性外,觸摸事件還包含下列三個用于跟蹤觸摸的屬性:
    (1)touches:表示當(dāng)前跟蹤的觸摸操作的Touch對象的數(shù)組
    (2)targetTouchs:特定與事件目標(biāo)的Touch對象的數(shù)組
    (3)changeTouched:表示自上次觸摸以來發(fā)生了什么變化的Touch對象的數(shù)組
手勢事件
  • gesturestart:當(dāng)一個手指已經(jīng)按在屏幕上而另一個手指又觸摸屏幕時觸發(fā)
  • gesturechange:當(dāng)觸摸屏幕的任何一個手指的位置發(fā)生變化時觸發(fā)
  • gestureend:但任何一個手指從屏幕上面移開時觸發(fā)。
    注意:在一個元素上設(shè)置事件處理程序,意味著兩個手指必須同時位于該元素的范圍之內(nèi),才能觸發(fā)手勢事件(這個元素就是目標(biāo)),由于這些事件冒泡,所以將事件處理程序放在文檔上也可以處理所有手勢事件,此時事件的目標(biāo)就是兩個手指都位于其范圍 內(nèi)的那個元素。
    特殊屬性:
  • rotation:表示手指變化引起的旋轉(zhuǎn)角度,負值表示逆時針旋轉(zhuǎn)
  • scale:表示兩個手指尖距離的變化情況,這個值從1開始,并隨距離拉大而增長,隨距離縮小而減小

內(nèi)存和性能

事件委托

事件委托利用了事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件

EventUtil.addHandler(document,'click',function(event){
    event = EventUtil.getTarget(event);
    switch(target.id){
     case "dosomething":
             handleDosomething()
             break;
     case "goSomewhere":
            handleGosomgwhere()
            break;
  }
});

事件委托的優(yōu)點:

  • document對象很快就可以訪問,而且在頁面生命周期的任何時點上為它添加事件處理程序。換句話說,只要可點擊的元素呈現(xiàn)在頁面上,就可以立刻具備適當(dāng)?shù)墓δ堋?/li>
  • 在頁面中設(shè)置事件處理程序所需的時間更少,只添加一個事件處理程序所需的DOM引用更少,所花的時間也更少。
  • 整個頁面占用的內(nèi)存空間更少,能夠提升整體性能

模擬事件

DOM中的事件模擬
  • ①document.createEvent()創(chuàng)建一個event對象,可接受一個參數(shù),表示要創(chuàng)建的事件類型的字符串(UIEvetnts,MouseEvents,MutationEvents,HTMLEvents)
  • ②創(chuàng)建的event對象都對應(yīng)有一個特殊的初始化方法,傳入適當(dāng)?shù)臄?shù)據(jù)可以初始化該evnet對象
  • ③在DOM節(jié)點上使用dispatchEvent()方法觸發(fā)這個事件
自定義事件

自定義事件不是由DOM原生觸發(fā)的額,它的目的是讓開發(fā)人員創(chuàng)建自己的事件。

  • ①調(diào)用document.createEvent('CustomEvent')創(chuàng)建一個自定義事件對象,有一個名為initCustomEvent()的方法接收以下4個參數(shù):
    • type(字符串):觸發(fā)的事件類型
    • bubbles(布爾值):表示時間是否應(yīng)該冒泡
    • cancelable(布爾值):表示事件是否可以取消
    • detaitl(對象):任意值,保存在event對象的detail屬性中
  • ②在對應(yīng)節(jié)點上綁定該事件
  • ③使用dispatchEvent(event)事件觸發(fā)。

此處跳過對IE的事件模擬。

以上參考紅寶書《高程三》
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 事件流 事件流描述的是從頁面中接受事件的順序。但是IE和Netscape開發(fā)團隊提出了差不多相反的事件流的概念。I...
    losspm閱讀 315評論 0 0
  • 一、事件流 1.1 事件流 事件流:從頁面中接受事件的順序 事件冒泡:即事件開始時由最具體的元素(文檔中嵌套層次最...
    范小飯_閱讀 1,171評論 1 9
  • JavaScript 程序采用了異步事件驅(qū)動編程模型。在這種程序設(shè)計風(fēng)格下,當(dāng)文檔、瀏覽器、元素或與之相關(guān)的對象發(fā)...
    劼哥stone閱讀 1,335評論 3 11
  • 事件基本概念 事件類型:用來說明發(fā)生什么類型事件的字符串,即事件名。事件目標(biāo):發(fā)生事件的對象。當(dāng)談?wù)撌录r,會同時...
    留七七閱讀 1,101評論 0 11
  • 人生如戲,戲如人生。在各自前進的路上,你會遇見許多人,許多故事,許多風(fēng)景。幸福的是,奔跑從未停止。你就要相...
    未及風(fēng)深閱讀 2,013評論 1 3

友情鏈接更多精彩內(nèi)容