<input type="button" value="按鈕" onclick="alert('Lee');" />//注意單雙引號腳本模型
var input = document.getElementsByTagName('input')[0];//得到input對象input.onclick = function () {//匿名函數執行 alert('Lee');};事件對象
事件對象,我們一般稱作為event對象,這個對象是瀏覽器通過函數把這個對象作為參數傳遞過來的。input.onclick = function (evt) { var e = evt || window.event;//實現跨瀏覽器兼容獲取event對象 alert(e);};直接接收event對象,是W3C的做法,早期IE不支持,IE自己定義了一個event對象,直接在window.event獲取即可鼠標事件
通過鼠標事件對象可以獲取到鼠標按鈕信息和屏幕坐標獲取等可視區及屏幕坐標<!DOCTYPE html><head> <meta charset="UTF-8"> <title>Document</title></head><body> <div style="width:300px;margin-left:100px;height:300px;background-color: red"></div></body><script type="text/javascript"> document.getElementsByTagName("div")[0].onclick = function (evt) { var e = evt || window.event; console.log(e.clientX + ',' + e.clientY); console.log(e.screenX + ',' + e.screenY); console.log(e.offsetX + ',' + e.offsetY); console.log(e.pageX + ',' + e.pageY); };</script></html>鍵盤事件
鍵碼
在發生keydown和keyup事件時,event對象的keyCode屬性中會包含一個代碼,與鍵盤上一個特定的鍵對應。對數字字母字符集,keyCode屬性的值與ASCII碼中對應小寫字母或數字的編碼相同。字母中大小寫不影響。<script type="text/Javascript"> document.onkeydown = function (evt) { console.log(evt.keyCode);//按任意鍵,得到相應的keyCode };</script>不同的瀏覽器在keydown和keyup事件中,會有一些特殊的情況:在Firefox和Opera中,分號鍵時keyCode值為59,也就是ASCII中分號的編碼;而IE和Safari返回186,即鍵盤中按鍵的鍵碼。字符編碼
Firefox、Chrome和Safari的event對象都支持一個charCode屬性,這個屬性只有在發生keyPRess事件時才包含值,而且這個值是按下的那個鍵所代表字符的ASCII編碼。此時的keyCode通常等于0或者也可能等于所按鍵的編碼。IE和Opera則是在keyCode中保存字符的ASCII編碼。function getCharCode(evt) { var e = evt || window.event; if (typeof e.charCode == 'number') { return e.charCode; } else { return e.keyCode; }}PS:可以使用String.fromCharCode()將ASCII編碼轉換成實際的字符。W3C與IE事件模型
事件對象屬性
function getTarget(evt) { var e = evt || window.event; return e.target || e.srcElement;//兼容得到事件目標DOM對象}document.onclick = function (evt) { var target = getTarget(evt); alert(target);};target和currentTarget的區別
currentTarget始終是監聽事件者,而target是事件的真正發出者<!DOCTYPE html><head> <meta charset="UTF-8"> <title>Document</title></head><body> <div id="outdiv" style="width:300px;margin-left:100px;height:300px;background-color: red"> <div id="indiv" style="width:100px;height: 100px;background-color: blue;"></div> </div></body><script type="text/javascript"> document.getElementById("outdiv").onclick = function (evt) { var e = evt || window.event; console.log(e.currentTarget); console.log(e.target); };</script></html>藍色框表示點擊藍色區域時的輸出,紅色框表示點擊紅色區域時的輸出。
事件流
事件流是描述的從頁面接受事件的順序,當幾個都具有事件的元素層疊在一起的時候,那么你點擊其中一個元素,并不是只有當前被點擊的元素會觸發事件,而層疊在你點擊范圍的所有元素都會觸發事件。事件流包括兩種模式:冒泡和捕獲。事件冒泡,是從里往外逐個觸發。事件捕獲,是從外往里逐個觸發。那么現代的瀏覽器默認情況下都是冒泡模型,而捕獲模式則是早期的Netscape默認情況。而現在的瀏覽器要使用DOM2級模型的事件綁定機制才能手動定義事件流模式。在阻止冒泡的過程中,W3C和IE采用的不同的方法,那么我們必須做一下兼容。
function stopPro(evt) { var e = evt || window.event; window.event ? e.cancelBubble = true : e.stopPropagation(); }事件綁定
傳統事件綁定的問題
前面定義的事件函數會被后面定義的事件函數覆蓋window.onload = function () {//第一組程序項目或第一個JS文件 alert('Lee');};window.onload = function () {//第二組程序項目或第二個JS文件,會覆蓋上面的函數 alert('Mr.Lee');};解決覆蓋問題<script type="text/javascript"> function addEvent(obj, type, fn) {//取代傳統事件處理函數 var saved = null;//保存每次觸發的事件處理函數 if (typeof obj['on' + type] == 'function') {//判斷是不是事件 saved = obj['on' + type];//如果有,保存起來 } obj['on' + type] = function () { if (saved) saved();//執行上一個 fn.call(this);//執行函數,把this傳遞過去 }; } var box = document.getElementById("outdiv"); addEvent(box,"click",function(){ console.log("fun1"); }); addEvent(box,"click",function(){ console.log("fun2"); }); addEvent(box,"click",function(){ console.log("fun3"); });</script>W3C事件處理函數
“DOM2級事件”定義了兩個方法,用于添加事件和刪除事件處理程序的操作:addEventListener()和removeEventListener()。所有DOM節點中都包含這兩個方法,并且它們都接受3個參數;事件名、函數、冒泡或捕獲的布爾值(true表示捕獲,false表示冒泡)。window.addEventListener('load', function () { alert('Lee');}, false);window.addEventListener('load', function () { alert('Mr.Lee');}, false);W3C的現代事件綁定比我們自定義的好處就是:1.不需要自定義了;2.可以屏蔽相同的函數;3.可以設置冒泡和捕獲。window.addEventListener('load', init, false);//第一次執行了window.addEventListener('load', init, false);//第二次被屏蔽了IE事件處理函數
IE實現了與DOM中類似的兩個方法:attachEvent()和detachEvent()。這兩個方法接受相同的參數:事件名稱和函數。在使用這兩組函數的時候,先把區別說一下:1.IE不支持捕獲,只支持冒泡;2.IE添加事件不能屏蔽重復的函數;3.IE中的this指向的是window而不是DOM對象。4.在傳統事件上,IE是無法接受到event對象的,但使用了attchEvent()卻可以,但有些區別。函數重復問題<script type="text/javascript"> var box = document.getElementById("outdiv"); box.attachEvent('onclick', init); box.attachEvent('onclick', init); function init(){ alert("init") }</script>this問題<script type="text/javascript"> var box = document.getElementById("outdiv"); box.attachEvent('onclick', function () { alert(this === window);//this指向的window }); box.attachEvent('onclick', function () { toBlue.call(box);//可以把this直接call過去 });</script>event對象傳參<script type="text/javascript"> var box = document.getElementById("outdiv"); box.onclick = function (evt) { alert(evt);//undefined }; //定義了傳統事件后,還可以繼續綁定事件,不會覆蓋 box.attachEvent('onclick', function (evt) { alert(evt);//object alert(evt.type);//click });</script>PS:IE中的事件綁定函數attachEvent()和detachEvent()可能在實踐中不去使用,有幾個原因:1.IE9就將全面支持W3C中的事件綁定函數;2.IE的事件綁定函數無法傳遞this;3.IE的事件綁定函數不支持捕獲;4.同一個函數注冊綁定后,沒有屏蔽掉;5.有內存泄漏的問題。至于怎么替代,我們將在以后的項目課程中探討。事件對象的其他補充
relatedTarget屬性
在W3C提供了一個屬性:relatedTarget;這個屬性可以在mouSEOver和mouseout事件中獲取從哪里移入和從哪里移出的DOM對象。<script type="text/javascript"> var box = document.getElementById("indiv"); box.onmouseover = function (evt) {//鼠標移入box console.log(evt.relatedTarget);//獲取移入box最近的那個元素對象 } box.onmouseout = function (evt) {//鼠標移出box console.log(evt.relatedTarget);//獲取移出box最近的那個元素對象 }</script>IE提供了兩組分別用于移入移出的屬性:fromElement和toElement,分別對應mouseover和mouseout。<script type="text/javascript"> var box = document.getElementById("indiv"); box.onmouseover = function (evt) {//鼠標移入box console.log(window.event.fromElement.tagName);//獲取移入box最近的那個元素對象span } box.onmouseout = function (evt) {//鼠標移入box console.log(window.event.toElement.tagName);//獲取移入box最近的那個元素對象span }</script>組織瀏覽器默認行為
<script type="text/javascript"> link.onclick = function () { alert('Lee'); return false;//直接給個假,就不會跳轉了。 }; link.onclick = function (evt) { evt.preventDefault();//W3C,阻止默認行為,放哪里都可以 alert('Lee'); }; link.onclick = function (evt) { //IE,阻止默認行為 window.event.returnValue = false; alert('Lee'); };</script>阻止右鍵菜單
<script type="text/javascript"> document.addEventListener("contextmenu",function(event){ event.preventDefault(); console.log("hehe"); },false);</script>卸載前事件:beforeunload
用beforeunload事件,在某些瀏覽器上(chrome、ie、firefox)可以監聽到瀏覽器關閉操作,能夠在關閉之前,彈出一個對話框,讓用戶選擇是否關閉<script type="text/javascript"> window.addEventListener("beforeunload", function (e) { var confirmationMessage = '確定離開此頁嗎?本頁不需要刷新或后退'; (e || window.event).returnValue = confirmationMessage; // Gecko and Trident return confirmationMessage;// Gecko and WebKit });</script>
新聞熱點
疑難解答