一.摘要
本系列文章是爲了抽象通用的,跨瀏覽器的腳本方法.
本篇文章爲腳本庫添加跨瀏覽器的獲取事件對象的方法, 重點是講解javascript中的事件對象的原理.希望通過分享微薄的知識告訴大家如何進行"加法運算"而不是死記硬背"1+1=2".
二.實現效果
本次添加的兩個函數用於獲取事件對象, 事件對象中包含很多的信息,比如鼠標的座標, 從而實現自己想要的功能.
實例一可以在屏幕上捕獲鼠標按鍵代碼和鍵盤按鍵代碼:
實例二實現重寫鼠標右鍵菜單:
三.事件對象簡介
事件源和事件對象就相當於C#中事件函數的sender和EventArgs參數.
事件源是產生事件的元素本身, 而事件對象則帶有事件相關的信息.事件對象只有在發生事件時才被創建, 並且只能在事件中訪問.當事件關聯的處理函數執行完畢後, 事件對象就被銷燬.
事件對象帶有很多有用的信息,比如屏幕座標,按鍵代碼,是否冒泡等.但是可惜的是FireFox支持的DOM事件模型和IE的事件模型並不完全一致,獲取事件對象的方式也不相同.在IE中通過window.event使用當前的事件對象,而DOM則規定事件對象要作爲唯一參數傳遞給事件處理函數.
四.實現代碼
我們的ScriptHelper類又要添加兩個新方法了:
/* 獲取事件對象
使用舉例: <div οnclick=" var oEvent=ScriptHelper.getEvent();"></div>
注意事項: 只能在事件中使用. 比如onclick中. 不能在自定義方法中使用.
*/
scriptHelper.prototype.getEvent = function()
{
if( window.event )
{
return window.event;
}
else
{
return this.getEvent.caller.arguments[0];
}
}
/* 取消冒泡事件
使用舉例: <div οnclick=" var oEvent=ScriptHelper.cancelBubble();"></div>
注意事項: 只能在事件中使用. 比如onclick中. 不能在自定義方法中使用.
*/
scriptHelper.prototype.cancelBubble = function()
{
if( window.event )
{
window.event.cancelBubble = true;
}
else
{
return this.cancelBubble.caller.arguments[0].cancelBubble = true;
}
}
這兩個方法十分簡單.getEvent 用於獲取事件對象. cancelBubble和getEvent類似,但不是返回事件對象, 而是取消事件對象的冒泡事件.
也許有人會覺得getEvent 和cancelBubble中有重複代碼,認爲可以在cancelBubble中調用getEvent 獲取事件對象,然後再取消冒泡事件. 然而不能這麼做, 這兩個事件都只能用在事件處理函數中, cancelBubble已經是一個自定義方法, 不能在自定義方法中使用getEvent .原因是在DOM事件中,事件對象是事件的唯一參數.對於FireFox我們是通過caller.arguments[0]來捕獲事件對象,caller表示此方法的調用者, 必須爲事件. 下文中還有對於事件參數的講解.
五.應用實例
實例一 在屏幕上捕獲鼠標按鍵代碼和鍵盤按鍵代碼
實例代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>ScriptHelper 類測試 -- 事件對象實例 -- 獲取鍵盤鼠標按鍵代碼</title>
<script src="http://files.cnblogs.com/zhangziqiu/ScriptHelper.js" type="text/javascript"></script>
<style type="text/css">
.cursorHand { cursor:pointer;}
</style>
</head>
<body >
<script type="text/javascript">
function getKeyCode()
{
var oEvent = ScriptHelper.getEvent();
alert( "KeyCode:" + oEvent.keyCode);
}
function getMouseButtonCode()
{
var oEvent = ScriptHelper.getEvent();
alert( "Mouse Button Code:" + oEvent.button);
}
ScriptHelper.addEventListener( document, "keydown", getKeyCode );
ScriptHelper.addEventListener( document, "mousedown", getMouseButtonCode );
</script>
</body>
</html>
實例說明:
本實例中使用了ScriptHelper.getEvent方法獲取事件對象,並且獲取了事件對象中的鍵盤代碼和鼠標按鍵代碼.注意實例中是使用ScriptHelper.addEventListener將getKeyCode和getMouseButtonCode添加到事件上.此時getKeyCode函數等同於onkeydown事件, 所以在getKeyCode函數中調用ScriptHelper.getEvent就等同於在onkeydown事件中調用.
但是注意不能這麼寫:
<body onkeydown="getKeyCode();">
因爲上面的代碼等同於:
body.onkeydown = function()
{
getKeyCode();
}
實例二 重寫鼠標右鍵菜單
實例代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>ScriptHelper 類測試 -- 事件對象實例 -- 重寫鼠標右鍵菜單</title>
<script src="http://files.cnblogs.com/zhangziqiu/ScriptHelper.js" type="text/javascript"></script>
<style type="text/css">
.cursorHand { cursor:pointer;}
.menu
{
background:#FFFFFF none repeat scroll 0 0;
border:1px solid #ACA899;
color:#000000;
font-size:12px;
position:absolute;
display:none;
}
.menu ul
{
list-style-image:none;
list-style-position:outside;
list-style-type:none;
margin:3px;
padding:3px;
}
.menu ul li
{
cursor:pointer;
margin-bottom:5px;
}
</style>
</head>
<body style="position:relative;">
<script type="text/javascript">
</script>
<div>測試文字: 歡迎訪問 http://zhangziqiu.cnblogs.com 一起學習,一起進步.</div>
<div id="mouseRightButtonMenu" class="menu" οnclick="ScriptHelper.cancelBubble();">
<ul>
<li id="divMouseMenu1">查看選中內容</li>
<li><a href="http://zhangziqiu.cnblogs.com" target="_blank">返回博客首頁</a></li>
</ul>
</div>
<script type="text/javascript">
//顯示鼠標右鍵菜單
function showMouseRightButtonMenu()
{
ScriptHelper.cancelBubble();
var oEvent = ScriptHelper.getEvent();
var menu = document.getElementById('mouseRightButtonMenu');
if( oEvent.button == 2)
{
menu.style.display="block";
menu.style.left = oEvent.clientX + "px";
menu.style.top = oEvent.clientY + "px";
}
}
//關閉鼠標右鍵菜單
function closeMouseRightButtonMenu()
{
var oEvent = ScriptHelper.getEvent();
if( oEvent.button == 0 || oEvent.button == 1)
{
ScriptHelper.closeDivCommon('mouseRightButtonMenu');
}
}
//空函數,用於取消FireFox默認的鼠標右鍵菜單
function blankMethod()
{
return false;
}
//添加鼠標右鍵菜單的相關事件
document.οnclick= blankMethod;
document.οndblclick= blankMethod;
ScriptHelper.addEventListener( document, "mousedown", showMouseRightButtonMenu );
ScriptHelper.addEventListener( document, "click", closeMouseRightButtonMenu );
ScriptHelper.addEventListener( document, "contextmenu", blankMethod );
/* 菜單項相關函數 */
function mouseMenu1()
{
ScriptHelper.closeDivCommon("mouseRightButtonMenu");
var selectText = "未選中任何內容";
if( window.getSelection )
{
selectText = window.getSelection().toString();
}
else if(document.selection && document.selection.createRange)
{
selectText = document.selection.createRange().text;
}
if( selectText!=null && selectText!="" )
{
alert(selectText);
}
}
var divMouseMenu1 = document.getElementById("divMouseMenu1");
if( divMouseMenu1!=null)
{
ScriptHelper.addEventListener( divMouseMenu1, "mousedown", mouseMenu1 );
}
</script>
</body>
</html>
實例說明:
此實例的代碼很多. 原理就是通過事件對象判斷是否單擊了右鍵, 如果是則彈出我們自己的鼠標右鍵菜單.
六.使用技巧
- IE中鼠標左鍵代碼是1,FF是0. IE和FF鼠標右鍵代碼都是2(oEvent.button)
- 取消默認的鼠標菜單, ie中重寫document.oncontentmenu方法, ff中要重寫document.click方法.
- 鼠標事件對象中的clientX和clientY可以獲取鼠標的座標
- ie中可以直接設置div的style.top和style.left屬性爲數字(比如100).ff中必須在數字後加"px"(比如100px)
- 不同的事件類型有順序: (1)mousedown (2)mouseup (3)click
七.事件對象詳解
獲取
IE中,事件對象是window對象的一個屬性.事件處理函數必須這樣訪問事件對象:
obj.οnclick=function()
{
var oEvent = window.event;
}
在DOM標準中,事件對象必須作爲唯一參數傳給事件處理函數:
obj.οnclick=function()
{
var oEvent = arguments[0];
}
除了使用argument[0]訪問此參數, 我們也可以指定參數名稱,上面的代碼等同於:
obj.οnclick=function(oEvent)
{
}
目前兼容DOM的瀏覽器有Firefox,Safari,Opera,IE7等.
通用的事件對象數據
在IE和DOM中,事件對象帶有的數據並不完全相同.但是我認爲只有完全的那些數據纔是值得我們使用的.下面是一些可以在IE和DOM中使用的事件對象數據.其中假設oEvent是事件對象.
1.獲取時間類型
var eventType = oEvent.type
2.獲取鍵盤按鍵代碼:
需要在keydown和keyup事件中使用.
var eventKeyCode = oEvent.keyCode
3.檢測Shift,Alt,Ctrl鍵是否被按下:
var isShift = oEvent.shiftKey;
var isAlt = oEvent.altKey;
var isCtrl = oEvent.ctrlKey;
返回的是boolean值.
4.獲取鼠標指針座標
var x = oEvent.clientX;
var y = oEvent.clientY;
八.總結
網上覆雜絢麗的腳本特效很多, 但是再複雜的特效也離不開基礎的事件和事件對象.一旦明白了原理, 相信大家的創造力可以做出來很多通用的優秀的腳本控件.比如下面這個網址中就有很多的特效:http://www.scriptlover.com/controls/context/ ,感謝"癡情客"在本系列的第二篇文章中提供了上面的網址.