最近更新:2014年03月02日09:54:44javascript
首發連接:http://www.cnblogs.com/sprying/p/3194899.html php
若是當前綁定事件的元素是表單的一個輸入元素;則this隱性指代可描述以下html
function(){ with(document){ with(this.form){ with(this){ // 元素屬性值 } } } }
二、DOM0級事件處理程序
事件處理程序是在元素的做用域中運行的,也就this引用當前元素。java
addEventListener
、removeEventListener
接受三個參數,最後一個參數是一個布爾值,false表示在冒泡階段調用事件處理程序,true是在捕獲階段調用。經過addEventListener添加的匿名函數將沒法移除。瀏覽器
attachEvent
、detachEvent
,此方法接受兩個參數,事件處理程序名稱和事件處理程序函數,事件都被添加到冒泡階段;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、事件對象
不管指定的何種事件處理程序(Dom0級或者Dom2級)都會傳入event對象,在事件處理程序內部,對象this始終等於綁定事件元素的currentTarget值,target指向事件實際目標。性能
事件處理程序中刪除按鈕也能阻止事件冒泡。目標元素在文檔中是事件冒泡的前提。測試
preventDefault
方法阻止事件的默認行爲。優化
stopPropagation
方法用於當即中止事件在Dom層次中的傳播。
只有事件處理程序執行期間,event對象纔會存在;一旦事件處理程序執行完成,event對象就會被銷燬。
在使用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取消事件默認行爲和冒泡。
當頁面徹底加載後(全部圖像、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屬性並添加到文檔後,纔會開始加載。
這個事件是在文檔被徹底卸載後觸發,而利用這個事件最多的狀況是清除引用,以免內存泄露;注意,此時操做Dom節點或元素的樣式,會致使錯誤;使用方式與load同樣,在window上綁定事件
當瀏覽器窗口被調整到一個新的高度或寬度時觸發;使用方式與load同樣,在window上綁定事件
在window對象上綁定;與resize相似,scroll元素會在文檔滾動期間重複被觸發,因此儘可能保持代碼簡單。
blur
在元素失去焦點時觸發,不冒泡
focus
在元素得到焦點時觸發,不冒泡
mousedown
->focus
->mouseup
->click
->mousedown
->mouseup
->click
->dbclick
在mousedown中阻止事件的默認行爲後,IE中,依舊得到焦點並觸發 Focus 事件,Firefox Safari Chrome Opera 中,沒有得到焦點,focus沒執行。分析:Focus 行爲是這些瀏覽器的默認行爲之一,能夠被取消執行。源 任何取消mousedown或mouseup事件,就會阻止click觸發;相應,阻止兩次click行爲也會阻止dbclick行爲。
shiftKey
、ctrlKey
、altKey
和metaKey
(在Window鍵盤中是window鍵,在mac中是Cmd),值都是布爾值。 IE8及以前,不支持metaKey屬性。
mouseover
和mouseout
有相關屬性(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; } }
只有在主鼠標按鈕被單擊(或回車鍵被按下)時纔會觸發click事件,檢測按鈕的信息也就不必了。對於mousedown
或mouseup
事件來講,其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。
將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級事件、文本事件
用戶按下鍵盤上的字符鍵時,觸發事件順序爲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參照表 主鍵盤上可輸入值的按鈕
數字鍵盤上的鍵的鍵碼值 功能鍵鍵碼值
控制鍵鍵碼值
只有在可編輯區域纔會觸發,其它待測試後添加 複製粘貼時,在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觸發DOMNodeRemoved
、DOMSubtreeModified
事件
appendChild、replaceChild、insertBefore觸發DOMNodeInserted
、DOMNodeInsertedIntoDocument
、DOMSubtreeModified
特性修改觸發DOMAttrModified
事件
Events | Opera 9+ | Firefox 3+ | Safari3+及Chrome | IE9+ |
---|---|---|---|---|
DOMSubtreeModified | - | 支持 | 支持 | 支持 |
DOMNodeInserted | 支持 | 支持 | 支持 | 支持 |
DOMNodeRemoved | 支持 | 支持 | 支持 | 支持 |
支持的瀏覽器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(); };
綁定時,在頁面卸載前能夠經過它彈出窗口,來取消卸載並繼續使用原有頁面。爲了顯示彈出窗,必須將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; })
支持的瀏覽器:IE9+、FireFox、Chrome、Safari 3.1+ 和 Opera 9+(Firefox 3+,Opera 9+,Safari 3+,Chrome 2+)
造成完整的DOM樹以後觸發,能夠將事件綁定至document或window,最終會冒泡到window,但它的實際目標是document,這個事件會在load以前觸發,
模擬兼容性的addDOMLoadEvent
IE FireFox 4+ 和Opera支持此事件,支持此事件的對象都有一個readyState屬性。可能包含下列5個值中的一個,但不必定都會經歷過uninitialized、loading、loaded、interactive(交互)、complet對於document而言,interactive會在與DOMContentLoaded大體相同時刻觸發,與load事件一塊兒使用時,沒法預料前後順序;另外交互階段也可能晚於完成階段。
readystatechange事件能夠做用於script(在IE和Opera中)link(僅IE中);通常該事件綁定在document上。
Js容錯代碼
window.onerror = function(e){ return true; }
5、內存與性能
頁面中事件處理程序的數量直接影響到頁面總體的運行性能,能夠經過事件委託來優化。若是可行的話,能夠考慮爲document對象添加一個事件處理程序。最適合採用事件委託的有click、mousedown、mouseup、keydown、keyup和keypress。
當頁面中元素被移除或替換時,若元素綁定的事件仍沒被移除,在IE中不會作出恰當處理,此時要先手工移除事件,否則會存在內存泄露。
模擬鼠標事件
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);
要查看詳細,可閱讀《JavaScript高級程序設計》