西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁(yè)編程開(kāi)發(fā)javascript|JQuery → JavaScript Event學(xué)習(xí)第四章:傳統(tǒng)的事件注冊(cè)模型

JavaScript Event學(xué)習(xí)第四章:傳統(tǒng)的事件注冊(cè)模型

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:beiyu時(shí)間:2010/2/6 0:13:05字體大。A-A+

作者:北玉點(diǎn)擊:619次評(píng)論:0次標(biāo)簽: Event

  • 類型:加殼脫殼大小:126KB語(yǔ)言:中文 評(píng)分:3.5
  • 標(biāo)簽:
立即下載

在這一章我會(huì)講解給元素注冊(cè)事件的最好的一種辦法,那就是:確保一個(gè)特定的事件在特定的HTML元素上發(fā)生并且能運(yùn)行特定的腳本。

在最古老的JavaScript瀏覽器里注冊(cè)事件只能通過(guò)內(nèi)聯(lián)模式。自從DHTML從根本上改變了你操作頁(yè)面的方法,事件的注冊(cè)就必須有擴(kuò)展性而且要

有很強(qiáng)的適應(yīng)性。所以就必須有相應(yīng)的事件模型。Netscape在第三代瀏覽器中就開(kāi)始了,IE在第四代瀏覽器開(kāi)始。

因?yàn)镹etscape 3就開(kāi)始支持這種新的事件注冊(cè)模型,在瀏覽器戰(zhàn)爭(zhēng)前就是事實(shí)上的標(biāo)準(zhǔn)。所以微軟不得不也是最后一次為了網(wǎng)上那些數(shù)不清的

使用了Netscape事件處理模型的頁(yè)面在兼容性上做出了讓步。

所以這兩個(gè)瀏覽器,事實(shí)上也是所有的瀏覽器都支持下面的代碼:


1 element.onclick = doSomething;

這是注冊(cè)一個(gè)事件的最好的辦法。無(wú)論什么時(shí)候用戶點(diǎn)擊了這個(gè)HTML元素,那么doSomething()都會(huì)執(zhí)行。這是唯一一個(gè)能夠跨瀏覽的注冊(cè)事件

的最好的辦法,深刻的理解這個(gè)模型和他的限制也是非常重要的。

因?yàn)闆](méi)有官方的標(biāo)準(zhǔn),所以我暫且稱為傳統(tǒng)事件注冊(cè)模型(traditional event registration model)。同時(shí),w3c也標(biāo)準(zhǔn)化了事件注冊(cè),微軟也

推出了高級(jí)模式,但是傳統(tǒng)模式依然能很好的運(yùn)行。


高級(jí)事件注冊(cè)程序
從Netscape 3/IE 4開(kāi)始,JavaScript能夠識(shí)別元素上的一系列事件的屬性。大多數(shù)HTML元素都有onclick,onmouseover,onkeypress等等屬性。

那些元素有哪些屬性--哪些元素支持哪些事件--都依賴于瀏覽器。

這些屬性對(duì)于他們本身也不是什么新穎的東西。在最古老的JavaScript瀏覽器里面就已經(jīng)存在了。


1 <a href="somewhere.html" onclick="doSomething()">


這里的A標(biāo)簽就有一個(gè)onclick參數(shù),在JavaScript里面就成為了A元素的屬性。那些古老的瀏覽器的事件處理程序只能通過(guò)在頁(yè)面源代碼里面設(shè)

置元素的參數(shù)這個(gè)辦法來(lái)注冊(cè)。如果你想讓這個(gè)腳本在所有的A標(biāo)簽執(zhí)行,那么你就需要再所有的鏈接上面加上onclick事件。

有了傳統(tǒng)事件注冊(cè)模型的到來(lái),這些onclick,onmouseover或者HTML元素的其他事件處理就都可以通過(guò)JavaScript來(lái)注冊(cè)了,F(xiàn)在你可以添加

、修改或者刪除一些事件處理程序而不用動(dòng)HTML的一絲一毫。當(dāng)你通過(guò)DOM來(lái)訪問(wèn)HTML元素的時(shí)候你就可以像下面這樣寫代碼了:
1 element.onclick = doSomething;

現(xiàn)在我們的示例函數(shù)doSomething()就注冊(cè)在了element元素的onclick屬性上,而且當(dāng)用戶點(diǎn)擊了這個(gè)元素函數(shù)就會(huì)執(zhí)行。注意事件的名字必須

都是小寫。

刪除這個(gè)事件處理程序,只要簡(jiǎn)單的讓點(diǎn)擊事件為空就行了:
1 element.onclick = null;


事件處理程序跟普通的JavaScript函數(shù)一樣。即使事件沒(méi)有發(fā)生的時(shí)候他也能執(zhí)行。如果你則這樣寫:
1 element.onclick()

那么doSomething一樣會(huì)執(zhí)行。雖然如果是一個(gè)不知道做什么或者產(chǎn)生錯(cuò)誤的函數(shù),這也沒(méi)有真實(shí)的事件發(fā)生。所以這是一種很少用來(lái)執(zhí)行事件

處理程序的方法。

微軟的IE5.5和更高版本的IE還有一個(gè)fireEvent()方法來(lái)完成同樣的事情。使用如下:
1 element.fireEvent('onclick')

 

沒(méi)有括號(hào)
需要注意的是注冊(cè)一個(gè)事件處理程序的時(shí)候你不能使用括號(hào)。onclick方法會(huì)被設(shè)置成為另外一個(gè)函數(shù)。如果你這樣寫


1 element.onclick = doSomething();

那么這個(gè)函數(shù)就會(huì)執(zhí)行并且它的結(jié)果會(huì)被注冊(cè)到onclick上。這可不是我們所期望的,我們只是希望在事件發(fā)生的時(shí)候函數(shù)能夠執(zhí)行。另外函數(shù)

寫出來(lái)是為了在事件發(fā)生的時(shí)候執(zhí)行,如果沒(méi)有關(guān)聯(lián)的執(zhí)行會(huì)造成嚴(yán)重的混亂和錯(cuò)誤。

所以我們?cè)谑录幚沓绦蛑袕?fù)制整個(gè)doSomething()方法。我們只是想在事件執(zhí)行的時(shí)候執(zhí)行這個(gè)函數(shù)。


this
在JavaScript里this關(guān)鍵字通常指函數(shù)的所有者。如果this指向事件發(fā)生的HTML元素,那么一切都是那么的美好,你可以很簡(jiǎn)單的做很多事情

。

不幸的是,雖然this非常的強(qiáng)大,但是如果你不是明確的知道他怎么運(yùn)作的話使用起來(lái)還是比較難的。關(guān)于這個(gè)我在另一個(gè)地方有詳細(xì)的討論

,在這我在傳統(tǒng)模式下做一些概述。

在傳統(tǒng)模式里this工作如下;注意這個(gè)跟內(nèi)聯(lián)模式稍微有些不同,F(xiàn)在this關(guān)鍵字在函數(shù)里,而不是在HTML的參數(shù)上。這個(gè)區(qū)別后面會(huì)另外講

的。


1 element.onclick = doSomething;

2 another_element.onclick = doSomething;

3

4 function doSomething() {

5 this.style.backgroundColor = '#cc0000';

6 }


如果你注冊(cè)了doSomething()作為任何一個(gè)HTML元素的click事件,那么當(dāng)用戶點(diǎn)擊那個(gè)元素的時(shí)候元素就得到一個(gè)背景。


匿名函數(shù)(Anonymous functions)
假設(shè)你想所有div在鼠標(biāo)經(jīng)過(guò)的時(shí)候改變背景色,然后在鼠標(biāo)離開(kāi)的時(shí)候返回背景色。正確的使用this,你可以這樣寫:


01 var x = document.getElementsByTagName('DIV');

02 for (var i=0;i<x.length;i++) {

03 x[i].onmouseover = over;

04 x[i].onmouseout = out;

05 }

06

07 function over() {

08 this.style.backgroundColor='#cc0000'

09 }

10

11 function out() {

12 this.style.backgroundColor='#ffffff'

13 }

這些代碼可以運(yùn)行,沒(méi)問(wèn)題。但是既然over()和out()都比較簡(jiǎn)單,那么就可以用一種更優(yōu)雅的匿名函數(shù)的方法來(lái)寫:
1 ...

2 for (var i=0;i<x.length;i++) {

3 x[i].onmouseover = function () {this.style.backgroundColor='#cc0000'}

4 x[i].onmouseout = function () {this.style.backgroundColor='#ffffff'}

5 }

反正onmouseover和onmouseout都是得到一個(gè)函數(shù)。與其拷貝over()和out(),不如直接定義一個(gè)事件處理程序在這個(gè)事件注冊(cè)的腳本上。既然

這些函數(shù)沒(méi)有名字,那么他們就是匿名函數(shù)。

這兩種注冊(cè)事件處理程序的方法基本上一樣,唯一的區(qū)別就是第二種的代碼量少一些。我非常喜歡匿名函數(shù)并且我會(huì)在注冊(cè)一個(gè)簡(jiǎn)單的事件處

理程序的時(shí)候使用它。


問(wèn)題
有一個(gè)小小的問(wèn)題就是傳統(tǒng)模式下onclick屬性只能包含一個(gè)函數(shù)。當(dāng)你想對(duì)一個(gè)事件注冊(cè)多個(gè)事件處理程序的時(shí)候就有問(wèn)題了。

比如,你已經(jīng)寫了一個(gè)可以拖動(dòng)的模塊。這個(gè)模塊注冊(cè)在onclick事件處理程序上所以當(dāng)你點(diǎn)擊它的時(shí)候就能開(kāi)始拖動(dòng)。你還寫了一個(gè)模塊可以

跟蹤用戶的點(diǎn)擊然后在onunload的時(shí)候發(fā)送信息給服務(wù)器,這樣就能知道你的頁(yè)面如何被使用的。這個(gè)模塊也需要在元素上注冊(cè)一個(gè)onclick事

件。

所以事情可能會(huì)是這樣:


1 element.onclick = startDragDrop;

2 element.onclick = spyOnUser;


這是就會(huì)發(fā)生錯(cuò)誤。第二個(gè)注冊(cè)程序會(huì)覆蓋第一個(gè),那么當(dāng)用戶點(diǎn)擊元素的時(shí)候就只有spyOnUser()執(zhí)行。

解決辦法就是注冊(cè)一個(gè)包含兩個(gè)方法的方法:
1 element.onclick = function () {startDragDrop(); spyOnUser()}

 

靈活的注冊(cè)
但是假設(shè)你沒(méi)有在你網(wǎng)站的每個(gè)頁(yè)面都使用兩個(gè)模塊。如果你還這樣寫:


1 element.onclick = function () {startDragDrop(); spyOnUser()}

你會(huì)得到一個(gè)錯(cuò)誤信息因?yàn)槠渲杏袀(gè)函數(shù)是未定義的。所以在注冊(cè)事件的時(shí)候要特別的小心。當(dāng)我們?cè)趕tartDragDrop()可能已經(jīng)注冊(cè)的時(shí)候還

想注冊(cè)spyOnUser(),那么我們可以這樣寫:
1 var old = (element.onclick) ? element.onclick : function () {};

2 element.onclick = function () {old(); spyOnUser()};

首先你定義一個(gè)變量old。如果元素已經(jīng)有了一個(gè)onclick的事件處理程序,那么就把它存入old,如果沒(méi)有,就設(shè)置old為一個(gè)空的function。

現(xiàn)在你要給一個(gè)div注冊(cè)一個(gè)新的事件處理程序。那么程序就會(huì)首先執(zhí)行old(),然后執(zhí)行spyOnUser(),F(xiàn)在新的事件處理程序添加在了元素上

,之前的注冊(cè)過(guò)的(如果有)也被包含了。

最后一個(gè)問(wèn)題:如果你想移除其中一個(gè)事件處理程序呢?現(xiàn)在我還不是很確定。你需要通過(guò)一些方法編輯element.onclick(),我還沒(méi)有研究過(guò)

這個(gè)問(wèn)題。

其他模式
我們看到傳統(tǒng)模式非常的簡(jiǎn)單易用,但是當(dāng)你給一個(gè)事件添加幾個(gè)程序的時(shí)候的解決辦法還是比較丑陋的。W3C的事件處理程序很好的解決了這

個(gè)問(wèn)題。

繼續(xù)
如果你想繼續(xù)學(xué)習(xí),請(qǐng)看下一章。

    易語(yǔ)言
    (22)易語(yǔ)言
    易語(yǔ)言開(kāi)發(fā)的軟件雖然經(jīng)常會(huì)被一些安全軟件誤報(bào)為病毒,但是易語(yǔ)言確實(shí)是一門可學(xué)很好的編程語(yǔ)言,因?yàn)槭侨形娜梢暱缙脚_(tái)編程語(yǔ)言,全中文支持,無(wú)需跨越英語(yǔ)門檻。全可視化編程,支持所見(jiàn)即所得程序界面設(shè)計(jì)和程序流程編碼。因此易語(yǔ)言也可以理解為簡(jiǎn)易的語(yǔ)言,跟語(yǔ)言語(yǔ)言等以英文為基礎(chǔ)的國(guó)外語(yǔ)言開(kāi)發(fā)平臺(tái),易語(yǔ)言學(xué)習(xí)起來(lái)更簡(jiǎn)單了。西西本次提供了易語(yǔ)言.完美破解版,十天學(xué)會(huì)易語(yǔ)言圖解教程教程易語(yǔ)言零起點(diǎn)教程易語(yǔ)言個(gè)皮膚...更多>>

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過(guò)難過(guò)
    • 5 囧
    • 3 圍觀圍觀
    • 2 無(wú)聊無(wú)聊

    熱門評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)