DOM Level 2 事件學習總結

術語

  1. UI events: 用戶接口事件,這些事件是由外設(好比鼠標,鍵盤)觸發的。
  2. UI Logical events: 設備無關的用戶接口事件,好比focus事件。
  3. Mutation events: 變更事件。這些事件在文檔結構發生改變的時候觸發。
  4. Capturing: 捕捉,便是事件在目標DOM節點處理以前,由事件目標前驅的事件處理程序處理。
  5. Bubbling: 捕捉,便是事件在目標DOM節點處理以後,由事件目標前驅的事件處理程序處理。
  6. Cancelable: 指示是否阻止DOM實現指定的默認事件處理程序處理。

事件流

基礎

每個Event事件對象都有一個EventTarget屬性,這個屬性是一個DOM節點的引用。當事件到達目標DOM節點,在這個DOM節點註冊的任何事件處理程序都會被觸發。事件處理程序的觸發順序是不肯定的。 javascript

事件流在事件的全部處理程序都執行完成以後纔算結束。固然,若是啓用了capture(事件捕捉)或者bubbling(事件冒泡)的話,事件流仍是能夠被修改的。 html

在事件流的執行過程當中,任何事件處理程序拋出異常,整個事件流都將中止。 java

Event capture(事件捕捉)

事件捕捉的處理流程是從文檔樹根節點,一直向下處理,直到目標節點才中止。 web

這裏要注意的是,調用Event接口的stopProgagation方法會組織事件流的後續處理。 瀏覽器

Event bubbling(事件冒泡)

事件冒泡是從目標節點先開始出來,而後順着目標節點的父節點,一級一級往上處理,知道文檔樹根節點。 dom

這裏要注意的是,調用Event接口的stopProgagation方法會組織事件流的後續處理。 優化

Event cancelation(事件取消)

有些事件是能夠取消的,由於這些事件,DOM實現會生成默認的事件處理程序。一個例子就是web瀏覽器內的超連接。 ui

一個或者多個事件處理程序調用Event接口的preventDefault方法就能取消事件的默認處理程序。 編碼

接口

EventTarget

interface EventTarget {
  void               addEventListener(in DOMString type, 
                                      in EventListener listener, 
                                      in boolean useCapture);
  void               removeEventListener(in DOMString type, 
                                         in EventListener listener, 
                                         in boolean useCapture);
  boolean            dispatchEvent(in Event evt)
                                        raises(EventException);
};

這邊值得說明的是dispatchEvent方法。經過這個方法咱們能夠手工觸發w3c的標準標準事件或者自定義事件。 spa

Event

// Introduced in DOM Level 2:
interface Event {
  // PhaseType
  const unsigned short      CAPTURING_PHASE                = 1;
  const unsigned short      AT_TARGET                      = 2;
  const unsigned short      BUBBLING_PHASE                 = 3;

  readonly attribute DOMString        type;
  readonly attribute EventTarget      target;
  readonly attribute EventTarget      currentTarget;
  readonly attribute unsigned short   eventPhase;
  readonly attribute boolean          bubbles;
  readonly attribute boolean          cancelable;
  readonly attribute DOMTimeStamp     timeStamp;
  void               stopPropagation();
  void               preventDefault();
  void               initEvent(in DOMString eventTypeArg, 
                               in boolean canBubbleArg, 
                               in boolean cancelableArg);
};

EventException

// Introduced in DOM Level 2:
exception EventException {
  unsigned short   code;
};
// EventExceptionCode
const unsigned short      UNSPECIFIED_EVENT_TYPE_ERR     = 0;

DocumentEvent

// Introduced in DOM Level 2:
interface DocumentEvent {
  Event              createEvent(in DOMString eventType)
                                        raises(DOMException);
};

createEvent接口返回一個Event對象,而後經過dispatchEvent方法分發事件,事件內部的相應的初始化方法會被調用,對事件對象進行初始化,以後就是按照事件流分發和處理事件。

示例:

var evt = document.createEvent( 'uiEvt' )

UIEvent

// Introduced in DOM Level 2:
interface UIEvent : Event {
  readonly attribute views::AbstractView  view;
  readonly attribute long             detail;
  void               initUIEvent(in DOMString typeArg, 
                                 in boolean canBubbleArg, 
                                 in boolean cancelableArg, 
                                 in views::AbstractView viewArg, 
                                 in long detailArg);
};

全部事件在dispatchEvent後都會調用initUIEvent對Event事件對象進行初始化。

UIEvent包括:

  1. DOMFocusIn
  2. DOMFocusOut
  3. DOMActivate

NOTE:這幾個事件平常開發並不經常使用的感受。固然,咱們能夠作一個實驗,就是關於DOMFocusIn focus DOMFocusOut blur 以及 DomActivate 事件的觸發順序。

<input type="text" id="t">

<script type="text/javascript">
    function onMouseDown (argument) {
        console.log( 'mouse down' );
    };
    function onClick (argument) {
        console.log( 'click' );
    };
    function onFocusIn (argument) {
        console.log( 'focus in ' );
    };
    function onFocus (argument) {
        console.log( 'focus' );
    };
    function onFocusOut (argument) {
        console.log( 'focus out' );
    };
    function onBlur (argument) {
        console.log( 'blur' );
    };
    function onActive (argument) {
        console.log( 'dom active and argument.detail is ' + argument.detail );
    };

    var input = document.getElementById('t');
    input.addEventListener( 'DOMFocusIn',onFocusIn );
    input.addEventListener( 'focus',onFocus );
    input.addEventListener( 'DOMFocusOut',onFocusOut );
    input.addEventListener( 'mousedown',onMouseDown );
    input.addEventListener( 'click',onClick );
    input.addEventListener( 'blur',onBlur );
    input.addEventListener( 'DOMActivate',onActive );
</script>

這段代碼執行後的結果就是:

mouse down 
focus 
focus in  
click 
dom active and argument.detail is 1 
dom active and argument.detail is 1 
blur 
focus out

MouseEvent

// Introduced in DOM Level 2:
interface MouseEvent : UIEvent {
  readonly attribute long             screenX;
  readonly attribute long             screenY;
  readonly attribute long             clientX;
  readonly attribute long             clientY;
  readonly attribute boolean          ctrlKey;
  readonly attribute boolean          shiftKey;
  readonly attribute boolean          altKey;
  readonly attribute boolean          metaKey;
  readonly attribute unsigned short   button;
  readonly attribute EventTarget      relatedTarget;
  void               initMouseEvent(in DOMString typeArg, 
                                    in boolean canBubbleArg, 
                                    in boolean cancelableArg, 
                                    in views::AbstractView viewArg, 
                                    in long detailArg, 
                                    in long screenXArg, 
                                    in long screenYArg, 
                                    in long clientXArg, 
                                    in long clientYArg, 
                                    in boolean ctrlKeyArg, 
                                    in boolean altKeyArg, 
                                    in boolean shiftKeyArg, 
                                    in boolean metaKeyArg, 
                                    in unsigned short buttonArg, 
                                    in EventTarget relatedTargetArg);
};

Mouse包括:

  1. click: 在用戶單擊主鼠標按鈕或者按下回車鍵時觸發
  2. mousedown: 在用戶按下任意鼠標按鈕時觸發
  3. mouseup: 在用戶釋放鼠標按鈕時觸發
  4. mouseover: 在鼠標指針位於一個元素外部,然後用戶將其移入另外一個元素內時觸發
  5. mousemove: 當鼠標指針在元素內部移時重複地觸發
  6. mouseout: 在鼠標指針位於一個元素上方,然後用戶將其移入另外一個元素時觸發

頁面上全部元素都支持鼠標事件,全部鼠標事件都會冒泡,也能夠被取消,而取消鼠標事件將會影響瀏覽器的默認行爲。

雖然鼠標事件主要使用鼠標來觸發,但在按下鼠標時鍵盤上的某些鍵的狀態也能夠影響到所要採起的操做。這些修改鍵就是ShiftCtrlAltMeta,它們常常被用來修改鼠標事件的行爲。DOM爲此規定了4個屬性,表示這些修改鍵的狀態:shiftKeyctrlKeyaltKeymetaKey。若是相應的鍵被按下了,則值爲true,不然值爲false。

只有在主鼠標按鈕被單擊時纔會觸發click事件,可是對於mousedown和mouseup事件,其event對象存在一個button屬性,表示按下或釋放的按鈕:

  • 0 表示主鼠標按鈕
  • 1 表示中間滾輪按鈕
  • 2 表示次鼠標按鈕

NOTE: IE中的button屬性與DOM的button屬性有很大差別

  • 0: 表示沒有按下按鈕。
  • 1: 表示按下了主鼠標按鈕。
  • 2: 表示按下了次鼠標按鈕。
  • 3: 表示同時按下了主、次鼠標按鈕。
  • 4: 表示按下了中間鼠標按鈕。
  • 5: 表示同時按下了主鼠標按鈕和中間的鼠標按鈕。
  • 6: 表示同時按下了次鼠標按鈕和中間的鼠標按鈕。
  • 7: 表示同時按下了三個鼠標按鈕。

Key events

DOM2標準並無提供任何關於鍵盤事件的標準。不過咱們平常開發過程當中,會用到三個鍵盤事件,分別是:

  1. keydown: 當用戶按下鍵盤上的任意鍵時觸發,若是按住不放會重複觸發此事件
  2. keypress: 當用戶按下鍵盤上的字符鍵時觸發,若是按住不放會重複觸發此事件
  3. keyup: 當用戶釋放鍵盤上的鍵時觸發

NOTE: Firefox、Chrome和Safari的event對象都支持一個charCode屬性,這個屬性只有在發生keypress事件時才包含值,並且這個值是按下的那個鍵所表明字符的ASCII編碼。IE和Opera則是在keyCode中保存字符的ASCII編碼。

MutationEvent

// Introduced in DOM Level 2:
interface MutationEvent : Event {
  // attrChangeType
  const unsigned short      MODIFICATION                   = 1;
  const unsigned short      ADDITION                       = 2;
  const unsigned short      REMOVAL                        = 3;

  readonly attribute Node             relatedNode;
  readonly attribute DOMString        prevValue;
  readonly attribute DOMString        newValue;
  readonly attribute DOMString        attrName;
  readonly attribute unsigned short   attrChange;
  void               initMutationEvent(in DOMString typeArg, 
                                       in boolean canBubbleArg, 
                                       in boolean cancelableArg, 
                                       in Node relatedNodeArg, 
                                       in DOMString prevValueArg, 
                                       in DOMString newValueArg, 
                                       in DOMString attrNameArg, 
                                       in unsigned short attrChangeArg);
};

變更事件包括如下不一樣事件類型:

  1. DOMSubtreeModified: 在DOM結構中發生任何變化時觸發
  2. DOMNodeInserted: 在一個節點做爲子節點被插入到另外一個節點中時觸發
  3. DOMNodeRemoved: 在節點從其父節點中被移除時觸發
  4. DOMNodeRemovedFromDocument: 在一個節點被直接從文檔中移除或經過子樹間接從文檔中移除以前觸發
  5. DOMNodeInsertedIntoDocument: 在一個節點被直接插入文檔或經過子樹間接插入文檔以後觸發
  6. DOMAttrModified: 在屬性被修改以後觸發
  7. DOMCharacterDataModified: 在文本節點的值發生變化時觸發

HTML event

HTML event是HTML4.0帶來的事件,以及支持DOM LEVEL 0的瀏覽器支持的標準事件。

NOTE:要建立一個HTML event定義事件Event對象,使用'HTMLEvents'做爲DocumentEvent.createEvent方法的參數。

//  Event {clipboardData: undefined, cancelBubble: false, returnValue: true, srcElement: null, defaultPrevented: false…}
var event = document.createEvent( 'HTMLEvents' )
//  NotSupportedError: The implementation did not support the requested type of object or operation.
var event = document.createEvent( 'load' )

HTML event包括如下不一樣事件類型:

  1. load
  2. unload
  3. abort
  4. error: 這個事件在image加載失敗的時候觸發,不過如今也支持OBJECT標籤,BODY標籤以及FRAMESET。
  5. select: 文本域中選中文本的時候觸發,只有INPUT以及TEXTAREA標籤支持。
  6. change: 只有INPUT,SELECT以及TEXTAREA標籤支持。
  7. submit: 只有FORM標籤支持。
  8. reset: 只有FORM標籤支持。
  9. focus: 只有LABEL, INPUT, SELECT, TEXTAREA, and BUTTON標籤支持。
  10. blur: 只有LABEL, INPUT, SELECT, TEXTAREA, and BUTTON標籤支持。
  11. resize
  12. scroll

參考文檔

  1. Document Object Model Events
  2. JavaScript 中的事件模擬
  3. 淺談DOM事件的優化
  4. [譯]什麼是Shadow Dom
  5. JavaScript並行運算新機遇——Web Workers的神奇魔法
  6. 事件模型在各瀏覽器中存在差別
  7. event.button
  8. [JavaScript]事件
相關文章
相關標籤/搜索