javascript原生事件總結

  javascript原生的事件,總結了一下,包括事件流、處理函數、事件對象這幾樣東西。而在兼容性方面,主要是老牌ie8以及如下和現代瀏覽器的差別,也就是ie和DOM事件標準的差別。javascript

  1. 事件流
    這個事件流ie4和Netscape4提出來的,可是兩個公司提出的事件流確實恰好相反的。ie的是事件冒泡,Netscape的是事件捕獲。
    ie會從觸發事件的元素一直往上冒泡直到document元素。如圖ie8如下包括ie8的

    Netscape則是從document元素開始往下傳播一直到觸發事件的元素。如圖

    而DOM標準則建議,將事件流分紅三個過程:
    首先捕獲階段:像Netscape那樣往下捕獲,可是捕獲階段目標元素不會接收到事件。
    而後是目標階段:就是觸發目標元素的事件。
    最後是冒泡階段:就是想ie那樣子的冒泡。
    如圖:

    可是ie9+,以及別的瀏覽器所實現的DOM事件流卻和標準有點不一樣。主要是事件流的最頂端延長到window。而且,在捕獲階段目標元素也會接受到一次事件。如圖:

    也就是說,目標元素的事件會兩次觸發。


  2. 事件處理程序
    有三種方式給元素綁定事件處理函數。
    a、HTML屬性
    <a onclick="alert('click')"></a>
    這樣使用在函數裏面直接能夠調用event,this指向當前元素。可是這種方式通常不適用。

    b、js中元素屬性
    這種方式的兼容性好,全部瀏覽器都支持。可是有一個兼容性問題。那就是ie8-的事件對象是做爲window的屬性而不是做爲參數傳進去的。因此要像下面這樣寫。
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <a href="##" id="a" style="display:block;width:100px;height:100px;background-color: #ccc;"></a>
        <script>
            document.getElementById('a').onclick = function(event){
                event = event || window.event;
                alert(event);
            }
    
        </script>
    </body>
    </html>


    c、DOM2事件綁定
    主要指的是元素的addEventListener()和removeEventListener()。前者綁定,後者刪除。
    這兩個函數都有三個參數,
    第一個是事件類型,有click,focus,blur等
    第二個是事件處理函數。
    第三個是個布爾值,true表明在捕獲階段調用處理函數,false表明在冒泡階段調用處理函數。
    要綁定事件:css

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <a href="##" id="a" style="display:block;width:100px;height:100px;background-color: #ccc;"></a>
        <script> document.getElementById('a').addEventListener('click',function(event){ alert(event); },false) </script>
    </body>
    </html>
     

    假如想解除綁定,有人可能會這樣:html

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <a href="##" id="a" style="display:block;width:100px;height:100px;background-color: #ccc;"></a>
        <script> document.getElementById('a').addEventListener('click',function(event){ alert(event); },false) document.getElementById('a').removeEventListener('click',function(event){ alert(event); },false) </script>
    </body>
    </html>

    可是這樣是不會成功的。由於函數是一個對象,兩個匿名函數是不一樣的對象,不相等。因此匿名函數是沒辦法解綁的。只能想下面這個,個函數一個名號。java

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <a href="##" id="a" style="display:block;width:100px;height:100px;background-color: #ccc;"></a>
        <script>
            var handler = function(event){ alert(event); } document.getElementById('a').addEventListener('click',handler,false) document.getElementById('a').removeEventListener('click',handler,false) </script>
    </body>
    </html>
     

    ie8-的瀏覽器不支持DOM2級事件,可是有相似的方法attachEvent()和detachEvent();用法上是同樣的,只是由於ie8-只有冒泡過程因此就沒有第三個參數。還有第一個參數要加個‘on’,好比click事件是‘onclick'。另外,函數內this指向window。jquery

  3. 事件對象
    chrome

     

     

    在js中全部的事件對象都繼承自Event。在chrome(左)和firefox(右)中Event對象的樣子。    

        能夠看到在瀏覽器中Event對象仍是有點區別的。可是下面的屬性和方法是公用的。瀏覽器

     

    bubbles 是否冒泡
    cancelable 是否能夠取消默認行爲
    currentTarget 目前元素
    target 目標元素
    defaultPrevented 是否已被阻止默認行爲
    type 事件類型
    eventPhase 事件流哪一個階段1捕獲 2目標 3冒泡
    detail 一些信息
    trusted js建立的爲false,瀏覽器建立爲true
    view 等同於window
    preventDefault() 阻止默認行爲
    stopPropagation() 阻止冒泡和捕獲
    stopImmediatePropagation() 當即阻止冒泡和捕獲

     

     

     

     

     

        在ie8—中事件對象,是這個樣子:框架

     

    cancelBubble 是否取消冒泡,爲true先頂一下stopPropagation()
    returnValue 返回值,爲false至關於preventDefault()
    srcElement 目標元素,至關於target
    type 事件類型

     

     




  4. UI事件
    load:頁面加載完、img圖像加載完、全部框架加載完、嵌入內容加載完在object元素觸發。在ie9+瀏覽器中,<script>元素也會觸發該事件。
    注意:頁面加載完表示,全部的外部css,js,圖像等都下載完。
      img元素,一旦加了src屬性就開始下載。
      script元素必定要插入文檔纔開始下載。
           這個事件的事件對象不會包含什麼信息,除了在兼容dom的瀏覽器中有target信息。
      在ie8以前沒有加進文檔的圖像不會生成event對象。
    unload:文檔被徹底卸載後觸發。
    resize:瀏覽器窗口被調整大小時。
    注意:ie8前event不提供任何屬性。
      兼容DOM的瀏覽器會提供target=document。
      Firefox老版本會在中止改變以後才觸發,如今全部瀏覽器都是每變一個像素都會觸發一次。
    scroll:在window對象發生,表示的是文檔被滾動。能夠經過body元素的scrollLeft和scrollTop來監控。
    注意:通過測試如今chrome,safari支持body上的這兩個屬性,ie11,firefox支持documentElement上的這兩個屬性。因此要這樣寫scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  5. 焦點事件
    focus,focusin 會在獲得焦點的元素上觸發,focus不冒泡,focusin冒泡。
    blur,focusout在失去焦點的元素上觸發,blur不冒泡,focuout冒泡。
    1. 鼠標和滾輪事件
      click:能夠經過鼠標或鍵盤觸發,冒泡。
      dblclick:經過雙擊鼠標主按鈕觸發(有些瀏覽器中鍵和右鍵也能夠)。冒泡。
        觸發dbclick的過程:mousedown--mouseup--click--mousedown--mouseup--click--dblclick
        可是ie8及之前的瀏覽器中有bug:mousedown--mouseup--click--mouseup--dblclick
      mousedown/mouseup:按下任意的鼠標鍵/釋放。冒泡。
        注意:當在一個元素按下會觸發這個元素的mousedown,若是不釋放移動到另外一個元素在釋放,就會觸發後一個元素的mouseup。

      mouseenter:從元素外部進入元素內部觸發。不冒泡。進入後代元素不觸發。ie、Firefox9+、Opera支持。
      mouseleave:從元素內部移出元素是觸發。不冒泡。進入後代元素不觸發。ie、Firefox9+、Opera支持。

      mouseover:進入元素內部時觸發。冒泡。
      mouseout:移出元素時觸發。冒泡。移進後代元素也觸發。

      mousemove:在元素內部移動的時候。冒泡。

      在這些事件中,event事件對象會有一些新增的屬性。
      在DOM標準中。
      clientX、clientY  
      which 一、左   二、右   三、中
      detail   單擊次數
      ctrlKey  
      altKey  
      metaKey  
      shiftKey  
      pageX、pageY  
      screenX、screenY  
      在ie8以及之前的瀏覽器

      clientX、clientY  
      button 0:沒按下,1:主鼠標,2:次鼠標,3:同時按下主次按鈕,4:中間按鈕,5:主和中間按鈕,6:按下次和右鼠標,7:三個都按下
      offsetX、offsetY  
      ctrlKey  
      altKey  
      metaKey  
      shiftKey  
      fromElement  mouseover
      toElement  mouseout
      jquery中對統一用which來代替button和which。
      if ( !event.which && button !== undefined ) { event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); }

       用位與運算,把button的一、三、五、7修正爲1;2,6修正爲2;dom


  6. 鍵盤與文本事件
    keydown:按下鍵盤任意鍵觸發,按着不放會重複觸發。
    keyup:釋放鍵盤按鍵是觸發。
      上面的事件都有一個keyCode,表示按下鍵的鍵碼。數字字母是ASCII中的數字和小寫字母的編碼。charCode爲0.
    在Firefox和Opera中,按下分號keyCode爲ASCII的59;ie,Safari和chreome中爲鍵碼186.

    keypress:按下字符鍵是觸發。ie9+的瀏覽器,charCode等於ASCII碼。此時的keyCode不肯定,不一樣瀏覽器多是0,鍵碼或ASCII碼。
    在ie8和Opera中,keyCode等於ASCII碼。因此跨瀏覽器:
      
    1. charCode = event.charCode || event.keyCode

    這三個事件的順序是keydown--keypress--keyup。前兩個事件在文本框變化以前。


  7. 變更事件DOMSubtreeModified:在DOM結構發生任何變化時候觸發,在其餘變更事件以後觸發。冒泡。目標是插入或者刪除的元素的父元素。DOMNodeInserted:在一個節點插入另外一個節點時觸發。冒泡,目標是被插入的節點,event.relatedNode是父元素,觸發時已經插入文檔。DOMNodeInsertedIntoDocument:在DOMNodeInserted以後觸發。在DOMNodeInserted以後觸發。不冒泡,目標是刪除的節點或後代節點,從刪除的節點到後代元素的順序。DOMNodeRemoved:在一個節點移除是觸發。冒泡。事件目標是被觸發的節點,event.relatedNode是父元素,觸發時未被從文檔中刪除。DOMNodeRemovedFromDocument:在DOMNodeRemoved以後觸發。不冒泡,目標是刪除的節點或後代節點,從刪除的節點到後代元素的順序。DOMAttrModified:特性被修改以後觸發。DOMCharacterDataModified:文本節點的值變化的時候觸發。這些事件要經過DOM2的綁定方法才能綁定成功。ie9+,O9+,FF3+,S3+,C支持。
相關文章
相關標籤/搜索