JavaScript事件

最近更新:2014年03月02日09:54:44javascript

首發連接:http://www.cnblogs.com/sprying/p/3194899.html php

1、事件處理程序

一、HTML事件處理程序

若是當前綁定事件的元素是表單的一個輸入元素;則this隱性指代可描述以下html

function(){
    with(document){
        with(this.form){
            with(this){
                // 元素屬性值
            }
        }
    }
}
二、DOM0級事件處理程序

事件處理程序是在元素的做用域中運行的,也就this引用當前元素。java

三、DOM2級事件處理程序

addEventListenerremoveEventListener接受三個參數,最後一個參數是一個布爾值,false表示在冒泡階段調用事件處理程序,true是在捕獲階段調用。經過addEventListener添加的匿名函數將沒法移除。瀏覽器

四、IE事件處理程序

attachEventdetachEvent,此方法接受兩個參數,事件處理程序名稱和事件處理程序函數,事件都被添加到冒泡階段;attachEvent方法內,this = window,相比Dom方法以添加事件相反順序執行。app

跨瀏覽器的事件處理程序函數

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);
    } else if (element.detachEvent) {
        element.detachEvent("on" + type, handler);
    } else {
        element["on" + type] = null;
    }
},
2、事件對象

一、Dom中事件對象

不管指定的何種事件處理程序(Dom0級或者Dom2級)都會傳入event對象,在事件處理程序內部,對象this始終等於綁定事件元素的currentTarget值,target指向事件實際目標。性能

事件處理程序中刪除按鈕也能阻止事件冒泡。目標元素在文檔中是事件冒泡的前提。測試

preventDefault方法阻止事件的默認行爲。優化

stopPropagation方法用於當即中止事件在Dom層次中的傳播。

只有事件處理程序執行期間,event對象纔會存在;一旦事件處理程序執行完成,event對象就會被銷燬。

二、IE中事件對象

在使用Dom0級、Dom2級方法添加事件處理程序時,event對象做爲window對象的一個屬性存在,若是使用attachEvent狀況下,event對象還能夠做爲參數被傳入事件處理程序函數裏。這裏的event的srcElement屬性指向的事件的實際目標,即等同於Dom中事件對象的target。

下面是兼容處理瀏覽器的事件對象

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;
    }
},

  

jQuery中事件中,統一了event.preventDefault、event.stopPropagation爲取消事件默認行爲和冒泡,統一了this爲當前對象,規定return false取消事件默認行爲和冒泡。

3、事件類型

一、UI事件

1.一、load

當頁面徹底加載後(全部圖像、JavaScript文件、CSS文件等外部資源)就會觸發window上面的load事件。 對於網頁load,有兩種指定事件的方式

  • 第一種

      window.addEventListener("load", function (event) {
      });
    

      

  • 第二種

    /**
       * 圖像預加載
       */
      varimgObj = new Image();
      EventUtil.addHandler(imgObj, 'load', function (event) {
          console.log('Image loaded');
      });
      imgObj.src = 'http://imgsrc.baidu.com/forum/pic/item/3b26ab18972bd40711fb6a887b899e510fb3098c.jpg';
    

      

    script元素,設置了src屬性並添加到文檔後,纔會開始加載。

1.二、unload

這個事件是在文檔被徹底卸載後觸發,而利用這個事件最多的狀況是清除引用,以免內存泄露;注意,此時操做Dom節點或元素的樣式,會致使錯誤;使用方式與load同樣,在window上綁定事件

1.三、resize

當瀏覽器窗口被調整到一個新的高度或寬度時觸發;使用方式與load同樣,在window上綁定事件

1.四、scroll

在window對象上綁定;與resize相似,scroll元素會在文檔滾動期間重複被觸發,因此儘可能保持代碼簡單。

二、焦點事件

  • blur 在元素失去焦點時觸發,不冒泡

  • focus 在元素得到焦點時觸發,不冒泡

三、鼠標與滾輪事件

3.一、事件執行順序

mousedown->focus->mouseup->click->mousedown->mouseup->click->dbclick

在mousedown中阻止事件的默認行爲後,IE中,依舊得到焦點並觸發 Focus 事件,Firefox Safari Chrome Opera 中,沒有得到焦點,focus沒執行。分析:Focus 行爲是這些瀏覽器的默認行爲之一,能夠被取消執行。 任何取消mousedown或mouseup事件,就會阻止click觸發;相應,阻止兩次click行爲也會阻止dbclick行爲。

3.二、修改鍵

shiftKeyctrlKeyaltKeymetaKey(在Window鍵盤中是window鍵,在mac中是Cmd),值都是布爾值。 IE8及以前,不支持metaKey屬性。

3.三、相關元素

mouseovermouseout有相關屬性(event.relatedTarget);

IE8及其以前版本不支持relatedTarget,取代的是:mouseover事件的fromElement,mouseout事件的toElement

getRelatedTarget : function (event) {
    if (event.relatedTarget) {
        return event.relatedTarget;
    } else if (event.toElement) {
        return event.toElement;
    } else if (event.fromElement) {
        return event.fromElement;
    } else {
        return null;
    }
}

  

3.四、鼠標按鍵

只有在主鼠標按鈕被單擊(或回車鍵被按下)時纔會觸發click事件,檢測按鈕的信息也就不必了。對於mousedownmouseup事件來講,其event對象存在個button屬性,表示按下或釋放時的按鍵。注意:Opera只有在按主鼠標鍵時纔會觸發mousedown或mouseup。

// 鼠標事件的按鈕屬性
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; //滾輪
        }
    }
}

  

3.五、右鍵事件

mouseup事件中,event.button === 2,(若用mousedown,有一瀏覽器的button值始終是0。

3.六、鼠標滾輪事件

mousewheel事件處理程序指定給頁面中的任何元素或document對象,最終會冒泡到document(IE8)或window(IE九、Opera、Chrome、及Safari中),便可以處理鼠標滾輪的交互操做。當向前滾動鼠標時,wheelDelta是120的倍數,向後時,是-120的倍數。 Opera9.5以前版本中,wheelDelta的正負數是顛倒的。

Firefox支持一個名爲DOMMouseScroll的相似事件,滾輪的信息保存在detail裏,向前滾動時,屬性值是-3的倍數,能夠將該事件添加到任意元素,該事件會冒泡到window對象。

getWheelDelta : function (event) {
    if (event.wheelDelta) {
        return (browser.name == "opera" &&browser.version< 9.5) ?
        -event.wheelDelta : event.wheelDelta;
    } else {
        return -event.detail * 40;
    }
},  

// 瀏覽器綁定滾輪事件
EventUtil.addHandler(document, 'mousewheel', wheelFns);
EventUtil.addHandler(document, 'DOMMouseScroll', wheelFns);

  

四、鍵盤的DOM0級事件、文本事件

4.一、鍵盤事件

用戶按下鍵盤上的字符鍵時,觸發事件順序爲keydown->keypress->keyup;用戶按一個字符鍵不放時,可重複觸發keydown和keypress事件。它們的事件對象都支持keyCode屬性。

發生keypress事件意味按下的鍵會影響到屏幕中文本的顯示。可以插入和刪除字符的鍵都會觸發keypress事件。keypress的event支持字符編碼charCode屬性,可還沒發現什麼應用地方。

取得字符編碼後,就能夠用String.fromCharCode()將其轉換成實際的字符。

鍵盤事件也支持修改鍵,鍵盤事件對象裏面也有shiftKey、ctrlKey、altKey、和metaKey。IE不支持metaKey。

  • 快捷鍵

     document.onkeydown = function(e) {
          e = e || window.event;
          varkeycode = e.which ? e.which: e.keyCode;
          if (keycode == 13 || keycode == 108) { //若是按下ENTER鍵
              //在這裏設置你想綁定的事件
          }
      }
    

      

  • 快捷鍵與修改鍵

      // 鍵盤事件和修改鍵組合應用
      EventUtil.addHandler(document, 'keydown',
      function(e) {
          if (e.ctrlKey&&e.keyCode == 121) {
              console.log('Ctrl + F10');
          }
      }); 
      // 取消事件的默認行爲
      EventUtil.addHandler(document, 'keydown',
      function(e) {
          if (e.keyCode == 122) {
              EventUtil.preventDefault(e);
          }
      });
    

      

  • 屏蔽事件

    document.onkeydown = function (event) {
          event = event || window.event;
          var key = event.which || event.keyCode;
          ////屏蔽 Alt+ 方向鍵 → alert("不許你使用ALT+方向鍵前進或後退網頁!")
          if ((event.altKey) && ((key == 37) || (key == 39))) { 
              event.returnValue = false;
          }
          if ((key == 8) || (key == 116)) { //屏蔽 F5 刷新鍵
              event.keyCode = 0;
              event.returnValue = false;
          }
      }
    

      

JS判斷用戶按下的按鍵,根據按下的按鍵而後執行不一樣的操做:

document.body.onkeydown = window.onkeydown = function(e) {
    var keyCode;
    if (!e) e = window.event;
    if (document.all) {
        keyCode = e.keyCode;
    } else {
        keyCode = e.which;
    }
    if (keyCode == 37) {
        window.location.href = "http://www.phpernote.com";
    }
    if (keyCode == 39 || keyCode == 13) {
        window.location.href = "http://www.phpernote.com";
    }
}

  

附keyCode參照表 主鍵盤上可輸入值的按鈕

數字鍵盤上的鍵的鍵碼值 功能鍵鍵碼值

控制鍵鍵碼值

4.二、textInput

只有在可編輯區域纔會觸發,其它待測試後添加 複製粘貼時,在IE678觸發onpropertychange,其它瀏覽器促發oninput事件(HTML5)

function input(input, callback){
    if("onpropertychange"in input){//IE6/IE7/IE8
        input.onpropertychange =function(){
            if(window.event.propertyName =="value"){
                callback.call(this, window.event)
            }
        }
    }else{
// Fix Firefox Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=195696
        input.addEventListener("input", callback,false);
    }
}

  

五、變更事件

removeChild、replaceChild觸發DOMNodeRemovedDOMSubtreeModified事件

appendChild、replaceChild、insertBefore觸發DOMNodeInsertedDOMNodeInsertedIntoDocumentDOMSubtreeModified

特性修改觸發DOMAttrModified事件

Events Opera 9+ Firefox 3+ Safari3+及Chrome IE9+
DOMSubtreeModified - 支持 支持 支持
DOMNodeInserted 支持 支持 支持 支持
DOMNodeRemoved 支持 支持 支持 支持

4、HTML5事件

一、contextmenu

支持的瀏覽器IE 、FireFox、 Safari、 Chrome 和 Opera 11+

屏蔽右鍵菜單contentmenu,細微區別見http://jiake.iteye.com/blog/240492

document.getElementById("test").oncontextmenu = function (event) {
    //-- do something here
    // alert("ContextMenu Popup");
    //-- prevent the default behavior
    if (document.all)
        window.event.returnValue = false; // for IE
    else
        event.preventDefault();
};

  

二、beforeunload

綁定時,在頁面卸載前能夠經過它彈出窗口,來取消卸載並繼續使用原有頁面。爲了顯示彈出窗,必須將event.returnValue的值設置爲要顯示給用戶的字符串(對IE及FireFox而言),同時做爲函數的值返回(對Safari和Chrome而言)。Opera 11 及其以前的版本不支持。

// beforeunload事件
EventUtil.addHandler(window, "beforeunload", function (event) {
    event = EventUtil.getEvent(event);
    var message = "I'm really going to miss you if you go."
        event.returnValue = message;
    return message;
})

  

三、DOMContentLoaded

支持的瀏覽器:IE9+、FireFox、Chrome、Safari 3.1+ 和 Opera 9+(Firefox 3+,Opera 9+,Safari 3+,Chrome 2+)

造成完整的DOM樹以後觸發,能夠將事件綁定至document或window,最終會冒泡到window,但它的實際目標是document,這個事件會在load以前觸發,

模擬兼容性的addDOMLoadEvent

四、readystatechange

IE FireFox 4+ 和Opera支持此事件,支持此事件的對象都有一個readyState屬性。可能包含下列5個值中的一個,但不必定都會經歷過uninitialized、loading、loaded、interactive(交互)、complet對於document而言,interactive會在與DOMContentLoaded大體相同時刻觸發,與load事件一塊兒使用時,沒法預料前後順序;另外交互階段也可能晚於完成階段。

readystatechange事件能夠做用於script(在IE和Opera中)link(僅IE中);通常該事件綁定在document上。

五、onerror

Js容錯代碼

window.onerror =  function(e){
    return true;
}

  

5、內存與性能

一、事件委託 

頁面中事件處理程序的數量直接影響到頁面總體的運行性能,能夠經過事件委託來優化。若是可行的話,能夠考慮爲document對象添加一個事件處理程序。最適合採用事件委託的有click、mousedown、mouseup、keydown、keyup和keypress。

二、移除事件處理程序 

當頁面中元素被移除或替換時,若元素綁定的事件仍沒被移除,在IE中不會作出恰當處理,此時要先手工移除事件,否則會存在內存泄露。

6、模擬事件

一、DOM中的事件模擬

  • 模擬鼠標事件

      varbtn = document.getElementById("myBtn");
      var event = document.createEvent("MouseEvents");
      // type bubbles cancelable view(這個參數幾乎老是要設置爲document.defaultView) detail screenXscreenYclientXclientYctrlKey
      // altKeyshiftKeymetaKey button relatedTarget
      event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);
      btn.dispatchEvent(event);
    

      

  • 模擬鍵盤事件

      var textbox = document.getElementById("myTextbox"),
          event;
    
      //以DOM3級方式建立
      if (document.implementation.hasFeature("KeyboardEvents", "3.0")) {
          event = document.createEvent("KeyBoarEvent");
          // type bubbles canclable view key location(0表示默認主鍵盤,1表示左,2表示右,3表示數字鍵盤,4表示移動設備,5表示手柄)
          // modifiers(空格相隔的修改鍵列表) repeat
      event.initKeyboardEvent("keydown", true, true, document.defaultView, "a", 0, "Shift", 0);
      }
      textbox.dispatchEvent(event);
    

      

    二、IE中的事件模擬

要查看詳細,可閱讀《JavaScript高級程序設計》

相關文章
相關標籤/搜索