javascript參考教程(五)事件處理

來源:互聯網
上載者:User
 

事件處理 事件處理概述   事件處理是對象化編程的一個很重要的環節,沒有了事件處理,程式就會變得很死,缺乏靈活性。事件處理的過程可以這樣表示:發生事件 - 啟動事件處理常式 - 事件處理常式作出反應。其中,要使事件處理常式能夠啟動,必須先告訴對象,如果發生了什麼事情,要啟動什麼處理常式,否則這個流程就不能進行下去。事件的處理常式可以是任意 JavaScript 語句,但是我們一般用特定的自訂函數(function)來處理事情。 指定事件處理常式  指定事件處理常式有三種方法: 方法一 直接在 HTML 標籤中指定。這種方法是用得最普遍的。方法是:<標記 ... ... 事件="事件處理常式" [事件="事件處理常式" ...]>讓我們來看看例子:<body ... onload="alert('網頁讀取完成,請慢慢欣賞!')" onunload="alert('再見!')">這樣的定義<body>標記,能使文檔讀取完畢的時候彈出一個對話方塊,寫著“網頁讀取完成,請慢慢欣賞”;在使用者退出文檔(或者關閉視窗,或者到另一個頁面去)的時候彈出“再見”。 方法二 編寫特定對象特定事件的 JavaScript。這種方法用得比較少,但是在某些場合還是很好用的。方法是:<script language="JavaScript" for="對象" event="事件">
...
(事件處理常式代碼)
...
</script>例:<script language="JavaScript" for="window" event="onload">
  alert('網頁讀取完成,請慢慢欣賞!');
</script> 方法三 在 JavaScript 中說明。方法:<事件主角 - 對象>.<事件> = <事件處理常式>;用這種方法要注意的是,“事件處理常式”是真正的代碼,而不是字串形式的代碼。如果事件處理常式是一個自訂函數,如無使用參數的需要,就不要加“()”。例:...

function ignoreError() {
  return true;
}

...

window.onerror = ignoreError; // 沒有使用“()”

這個例子將 ignoreError() 函數定義為 window 對象的 onerror 事件的處理常式。它的效果是忽略該 window 對象下任何錯誤(由引用不允許訪問的 location 對象產生的“沒有許可權”錯誤是不能忽略的)。 事件詳解 onblur 事件 發生在視窗失去焦點的時候。  應用於:window 對象 onchange 事件 發生在文本輸入區的內容被更改,然後焦點從文本輸入區移走之後。捕捉此事件主要用於即時檢測輸入的有效性,或者立刻改變文檔內容。  應用於:Password 對象;Select 對象;Text 對象;Textarea 對象 onclick 事件 發生在對象被單擊的時候。單擊是指滑鼠停留在對象上,按下滑鼠鍵,沒有移動滑鼠而放開滑鼠鍵這一個完整的過程。  一個普通按鈕對象(Button)通常會有 onclick 事件處理常式,因為這種對象根本不能從使用者那裡得到任何資訊,沒有 onclick 事件處理常式就等於廢柴。按鈕上添加 onclick 事件處理常式,可以類比“另一個提交按鈕”,方法是:在事件處理常式中更改表單的 action, target, encoding, method 等一個或幾個屬性,然後調用表單的 submit() 方法。  在 Link 對象的 onclick 事件處理常式中返回 false 值(return false),能阻止瀏覽器開啟此串連。即,如果有一個這樣的串連:<a href="http://www.a.com" onclick="return false">Go!</a>,那麼無論使用者怎樣點擊,都不會去到 www.a.com 網站,除非使用者禁止瀏覽器運行 JavaScript。  應用於:Button 對象;Checkbox 對象;Image 對象;Link 對象;Radio 對象;Reset 對象;Submit 對象 onerror 事件 發生在錯誤發生的時候。它的事件處理常式通常就叫做“錯誤處理程式”(Error Handler),用來處理錯誤。上邊已經介紹過,要忽略一切錯誤,就使用:function ignoreError() {
  return true;
}

window.onerror = ignoreError;

 應用於:window 對象 onfocus 事件 發生在視窗得到焦點的時候。  應用於:window 對象 onload 事件 發生在文檔全部下載完畢的時候。全部下載完畢意味著不但 HTML 檔案,而且包含的圖片,外掛程式,控制項,小程式等全部內容都下載完畢。本事件是 window 的事件,但是在 HTML 中指定事件處理常式的時候,我們是把它寫在<body>標記中的。  應用於:window 對象 onmousedown 事件 發生在使用者把滑鼠放在對象上按下滑鼠鍵的時候。參考 onmouseup 事件。  應用於:Button 對象;Link 對象 onmouseout 事件 發生在滑鼠離開對象的時候。參考 onmouseover 事件。  應用於:Link 對象 onmouseover 事件 發生在滑鼠進入物件範圍的時候。這個事件和 onmouseout 事件,再加片的預讀,就可以做到當滑鼠移到映像串連上,映像更改的效果了。有時我們看到,在指向一個串連時,狀態列上不顯示地址,而顯示其它的資料,看起來這些資料是可以隨時更改的。它們是這樣做出來的:<a href="..."
   onmouseover="window.status='Click Me Please!'; return true;"
   onmouseout="window.status=''; return true;">   應用於:Link 對象 onmouseup 事件 發生在使用者把滑鼠放在對象上滑鼠鍵被按下的情況下,放開滑鼠鍵的時候。如果按下滑鼠鍵的時候,滑鼠並不在放開滑鼠的對象上,則本事件不會發生。  應用於:Button 對象;Link 對象 onreset 事件 發生在表單的“重設”按鈕被單擊(按下並放開)的時候。通過在事件處理常式中返回 false 值(return false)可以阻止表單重設。  應用於:Form 對象 onresize 事件 發生在視窗被調整大小的時候。  應用於:window 對象 onsubmit 事件 發生在表單的“提交”按鈕被單擊(按下並放開)的時候。可以使用該事件來驗證表單的有效性。通過在事件處理常式中返回 false 值(return false)可以阻止表單提交。  應用於:Form 對象 onunload 事件 發生在使用者退出文檔(或者關閉視窗,或者到另一個頁面去)的時候。與 onload 一樣,要寫在 HTML 中就寫到<body>標記裡。  有的 Web Masters 用這個方法來彈出“調查表單”,以“強迫”來者填寫;有的就彈出廣告視窗,唆使來者點擊串連。我覺得這種“onunload="open..."”的方法很不好,有時甚至會因為彈出太多視窗而導致資源缺乏。有什麼對來者說就應該在網頁上說完,不對嗎?  應用於:window 對象 關於對象化編程的語句  現在我們有實力學習以下關於對象化編程,但其實屬於上一章的內容了。 with 語句 為一個或一組語句指定預設對象。用法:with (<對象>) <語句>;with 語句通常用來縮短特定情形下必須寫的代碼量。在下面的例子中,請注意 Math 的重複使用: x = Math.cos(3 * Math.PI) + Math.sin(Math.LN10);
y = Math.tan(14 * Math.E);當使用 with 語句時,代碼變得更短且更易讀: with (Math) {
  x = cos(3 * PI) + sin(LN10);
  y = tan(14 * E);
} this 對象 返回“當前”對象。在不同的地方,this 代表不同的對象。如果在 JavaScript 的“主程式”中(不在任何 function 中,不在任何事件處理常式中)使用 this,它就代表 window 對象;如果在 with 語句塊中使用 this,它就代表 with 所指定的對象;如果在事件處理常式中使用 this,它就代表發生事件的對象。一個常用的 this 用法:<script>
...
function check(formObj) {
  ...
}
...
</script><body ...>
...
<form ...>
...
<input type="text" ... onchange="check( this.form)">
...
</form>
...
</body>這個用法常用於立刻檢測表單輸入的有效性。 自訂建構函式我們已經知道,Array(),Image()等建構函式能讓我們構造一個變數。其實我們自己也可以寫自己的建構函式。自訂建構函式也是用 function。在 function 裡邊用 this 來定義屬性。function <建構函式名> [(<參數>)] {
  ...
  this.<屬性名稱> = <初始值>;
  ...
}然後,用 new 建構函式關鍵字來構造變數:var <變數名> = new <建構函式名>[(<參數>)];構造變數以後,<變數名>成為一個對象,它有它自己的屬性——用 this 在 function 裡設定的屬性。以下是一個從網上找到的搜集瀏覽器詳細資料的自訂建構函式的例子:function Is() {
  var agent = navigator.userAgent.toLowerCase();
  this.major = parseInt(navigator.appVersion);  //主要版本號
  this.minor = parseFloat(navigator.appVersion);//全版本號碼
  this.ns = ((agent.indexOf('mozilla')!=-1) &&
             ((agent.indexOf('spoofer')==-1) && //是否 Netscape
              (agent.indexOf('compatible') == -1)));
  this.ns2 = (this.ns && (this.major == 3));    //是否 Netscape 2
  this.ns3 = (this.ns && (this.major == 3));    //是否 Netscape 3
  this.ns4b = (this.ns && (this.minor < 4.04)); //是否 Netscape 4 低版本
  this.ns4 = (this.ns && (this.major >= 4));    //是否 Netscape 4 高版本
  this.ie = (agent.indexOf("msie") != -1);      //是否 IE
  this.ie3 = (this.ie && (this.major == 2));    //是否 IE 3
  this.ie4 = (this.ie && (this.major >= 4));    //是否 IE 4
  this.op3 = (agent.indexOf("opera") != -1);    //是否 Opera 3
  this.win = (agent.indexOf("win")!=-1);        //是否 Windows 版本
  this.mac = (agent.indexOf("mac")!=-1);        //是否 Macintosh 版本
  this.unix = (agent.indexOf("x11")!=-1);       //是否 Unix 版本
}

var is = new Is();

這個建構函式非常完整的搜集了瀏覽器的資訊。我們看到它為對象定義了很多個屬性:major, minor, ns, ie, win, mac 等等。它們的意思見上面的注釋。把 is 變數定義為 Is() 對象後,用 if (is.ns) 這種格式就可以很方便的知道瀏覽器的資訊了。我們也可以從這個建構函式中看到,它也可以使用一般的 JavaScript 語句(上例中為 var 語句)。讓我們再來看一個使用參數的建構函式:function myFriend(theName, gender, theAge, birthOn, theJob) {
  this.name = theName;
  this.isMale = (gender.toLowerCase == 'male');
  this.age = theAge;
  this.birthday = new Date(birthOn);
  this.job = theJob
}var Stephen = new myFriend('Stephen', 'Male', 18, 'Dec 22, 1982', 'Student');從這個建構函式我們不但看到了參數的用法,還看到了不同的屬性用不同的資料型是可以的(上例五個屬性分別為:字串,布爾值,數字,日期,字串),還看到了建構函式裡也可以用建構函式來“構造”屬性。如果用了足夠的“保護措施”來避免無限迴圈,更可以用建構函式自身來構造自己的屬性。 使用架構和Cookies 使用架構  在講述 window 對象的時候,我們提到過,一個架構內的網頁也是 window 對象,也就是說,Frame 對象也是 window 對象。用最容易理解的話說,每一個 HTML 檔案佔用一個 window 對象,包括定義架構的網頁(“框架頁”)。在 IE 裡用“<iframe>”標記在文檔中插入的架構也是 window 對象,但是用“包含網頁”的方法(在 HTML 中顯示為“<!--webbot bot="include" ...-->”)讀取的 HTML 就不佔用獨自的 window 對象。每一個架構都是包含它的頁的 window 對象的一個子物件(不知道應該叫“屬性”不該),要引用它,可以用以下幾種方法之一:window.frames[x]
window.frames['frameName']
window.frameName  其中,x 指的是該 window 對象中指定的第幾個架構,與其它數組一樣,x 也是從零開始的。frameName 指的是該架構的名字,跟<frame>裡的“name”屬性一樣。  如果使用 window.frameName 指定的 window 對象又是一個框架頁,那麼引用它的架構的方法:window.frameName.subFrameName。以此類推。  要注意的時,無論在何處,引用“window”對象所返回的,都是“當前”window 對象。如果要訪問其它 window 對象,就要用到 parent 和 top 屬性。parent 指的是“父級”window 對象,也就是包含當前 window 對象的框架頁;top 指的是視窗最頂端的 window 對象。  使用架構還要密切留意你的 JavaScript 中定義的全域變數和自訂函數。它們都有它們的所屬——所在的 window 對象。要引用其它架構中的全域變數或自訂函數,都要用“視窗對象.架構對象[.架構對象…].全域變數或自訂函數”這種很煩的方法。  以上這個問題在建立串連時經常會被忽略:如果在<head>中定義了一個預設目標視窗(<base target="...">),在<a href="javascript:...">中,要知道輸入的 JavaScript 語句是在預設目標視窗中啟動並執行,必要時加一些“parent”“top”屬性。 使用 Cookies  我們已經知道,在 document 對象中有一個 cookie 屬性。但是 Cookie 又是什嗎?“某些 Web 網站在您的硬碟上用很小的文字檔儲存了一些資訊,這些檔案就稱為 Cookie。”—— MSIE 協助。一般來說,Cookies 是 CGI 或類似,比 HTML 進階的檔案、程式等建立的,但是 JavaScript 也提供了對 Cookies 的很全面的訪問權利。  在繼續之前,我們先要學一學 Cookie 的基本知識。  每個 Cookie 都是這樣的:<cookie名>=<值>  <cookie名>的限制與 JavaScript 的命名限制大同小異,少了“不能用 JavaScript 關鍵字”,多了“只能用可以用在 URL 編碼中的字元”。後者比較難懂,但是只要你只用字母和數字命名,就完全沒有問題了。<值>的要求也是“只能用可以用在 URL 編碼中的字元”。  每個 Cookie 都有失效日期,一旦電腦的時鐘過了失效日期,這個 Cookie 就會被刪掉。我們不能直接刪掉一個 Cookie,但是可以用設定失效日期早於現在時刻的方法來間接刪掉它。  每個網頁,或者說每個網站,都有它自己的 Cookies,這些 Cookies 只能由這個網站下的網頁來訪問,來自其他網站或同一網站下未經授權的地區的網頁,是不能訪問的。每一“組”Cookies 有規定的總大小(大約 2KB 每“組”),一超過最大總大小,則最早失效的 Cookie 先被刪除,來讓新的 Cookie“安家”。  現在我們來學習 使用 document.cookie 屬性。  如果直接使用 document.cookie 屬性,或者說,用某種方法,例如給變數賦值,來獲得 document.cookie 的值,我們就可以知道在現在的文檔中有多少個 Cookies,每個 Cookies 的名字,和它的值。例如,在某文檔中添加“document.write(document.cookie)”,結果顯示:name=kevin; email=kevin@kevin.com; lastvisited=index.html這意味著,文檔包含 3 個 Cookies:name, email 和 lastvisited,它們的值分別是 kevin, kevin@kevin.com 和 index.html。可以看到,兩個 Cookies 之間是用分號和空格隔開的,於是我們可以用 cookieString.split('; ') 方法得到每個 Cookie 分開的一個數組(先用 var cookieString = document.cookie)。  設定一個 Cookie 的方法是對 document.cookie 賦值。與其它情況下的賦值不同,向 document.cookie 賦值不會刪除掉原有的 Cookies,而只會增添 Cookies 或更改原有 Cookie。賦值的格式:document.cookie = ' cookieName=' + escape(' cookieValue')
     + ' ;expires=' + expirationDateObj. toGMTString();是不是看到頭暈了呢?以上不是粗體字的地方是要照抄不誤的,粗體字是要按實際情況做出改動的。cookieName 表示 Cookie 的名稱,cookieValue 表示 Cookie 的值,expirationDateObj 表示儲存著失效日期的日期對象名,如果不需要指定失效日期,則不需要第二行。不指定失效日期,則瀏覽器預設是在關閉瀏覽器(也就是關閉所有視窗)之後到期。  看到了上面的一些底線了嗎?這些是應該注意的地方。
  首先 escape() 方法:為什麼一定要用?因為 Cookie 的值的要求是“只能用可以用在 URL 編碼中的字元”。我們知道“escape()”方法是把字串按 URL 編碼方法來編碼的,那我們只需要用一個“escape()”方法來處理輸出到 Cookie 的值,用“unescape()”來處理從 Cookie 接收過來的值就萬無一失了。而且這兩個方法的最常用途就是處理 Cookies。其實設定一個 Cookie 只是“document.cookie = 'cookieName=cookieValue'”這麼簡單,但是為了避免在 cookieValue 中出現 URL 裡不準出現的字元,還是用一個 escape() 好。
  然後“expires”前面的分號:注意到就行了。是分號而不是其他。
  最後 toGMTString() 方法:設定 Cookie 的時效日期都是用 GMT 格式的時間的,其它格式的時間是沒有作用的。  現在我們來實戰一下。設定一個“name=rose”的 Cookie,在 3 個月後到期。var expires = new Date();
expires.setTime(expires.getTime() + 3 * 30 * 24 * 60 * 60 * 1000);
/*   三個月 x 一個月當作 30 天 x 一天 24 小時
   x 一小時 60 分 x 一分 60 秒 x 一秒 1000 毫秒 */
document.cookie = 'name=rose;expires=' + expires.toGMTString();為什麼沒有用 escape() 方法?這是因為我們知道 rose 是一個合法的 URL 編碼字串,也就是說,'rose' == escape('rose')。一般來說,如果設定 Cookie 時不用 escape(),那擷取 Cookie 時也不用 unescape()。  再來一次:編寫一個函數,作用是尋找指定 Cookie 的值。function getCookie(cookieName) {
  var cookieString = document.cookie;
  var start = cookieString.indexOf(cookieName + '=');
  // 加上等號的原因是避免在某些 Cookie 的值裡有
  // 與 cookieName 一樣的字串。
  if (start == -1) // 找不到
    return null;
  start += cookieName.length + 1;
  var end = cookieString.indexOf(';', start);
  if (end == -1) return unescape(cookieString.substring(start));
  return unescape(cookieString.substring(start, end));
}這個函數用到了字串對象的一些方法,如果你不記得了(你是不是這般沒記性啊),請快去查查。這個函數所有的 if 語句都沒有帶上 else,這是因為如果條件成立,程式啟動並執行都是 return 語句,在函數裡碰上 return,就會終止運行,所以不加 else 也沒問題。該函數在找到 Cookie 時,就會返回 Cookie 的值,否則返回“null”。  現在我們要刪除剛才設定的 name=rose Cookie。var expires = new Date();
expires.setTime(expires.getTime() - 1);
document.cookie = 'name=rose;expires=' + expires.toGMTString();可以看到,只需要把失效日期改成比現在日期早一點(這裡是早 1 毫秒),再用同樣的方法設定 Cookie,就可以刪掉 Cookie 了。 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.