posts - 297,  comments - 1618,  trackbacks - 0
            說(shuō)明:本文為《JavaScript高級(jí)程序設(shè)計(jì)》第9章學(xué)習(xí)筆記。

          一.今天的事件

           事件DOM的一部分,在DOM Level1中未定義任何事件,在Level中定義了一小部分子集,完整的事件是在Level3中規(guī)定的,該標(biāo)準(zhǔn)在2004年最終定案。

           Mozilla的事件模式與DOM標(biāo)準(zhǔn)最為接近,IE成為唯一一個(gè)對(duì)DOM事件模式缺乏良好支持的瀏覽器。

           

          二.事件流

           事件流意味著在頁(yè)面上可有不僅一個(gè),甚至多個(gè)元素響應(yīng)同一個(gè)事件。

          1.       冒泡型事件

          IE上的解決方案的綽號(hào)為冒泡的技術(shù)。冒泡型事件的基本思想是,時(shí)間按照最特定的目標(biāo)到最不特定的事件目標(biāo)的順序觸發(fā)。

          IE6.0中,<html/>元素也可接收冒泡的時(shí)間。

          2.       捕獲型事件

          Netscape Navigator4.0使用了捕獲型事件的解決方案。事件從最不確定的對(duì)象(document對(duì)象)開(kāi)始觸發(fā),然后到最精確。

          3DOM事件流

                 DOM同時(shí)支持兩種事件模型:捕獲型事件和冒泡型事件,但是,捕獲型事件先發(fā)生。兩種事件流會(huì)觸發(fā)DOM中的所有對(duì)象,從document對(duì)象開(kāi)始,也在document對(duì)象結(jié)束。

                 DOM事件模型的最獨(dú)特的性質(zhì)是,文本節(jié)點(diǎn)也觸發(fā)事件(在IE中不會(huì))。

           

          三.時(shí)間處理函數(shù)/監(jiān)聽(tīng)函數(shù)

          事件是用戶或?yàn)g覽器自身進(jìn)行的特定行為。這些事件都有自己的名字,如clickload等。用于響應(yīng)某個(gè)事件而調(diào)用的函數(shù)稱為事件處理函數(shù)

                 如果是JavaScript中分配的事件處理函數(shù),則需要首先獲得要處理對(duì)象的引用,然后將函數(shù)賦值給事件處理函數(shù)屬性,eg1.

                 var oDiv = document.getElementById(“div1”);
                 oDiv.onclick 
          = function() {
                 alert(“I was clicked.”);
          }

                 用這個(gè)分配方法,事件處理函數(shù)必須小寫,才能正確響應(yīng)事件。

                 Eg2. <div onclick=”alert(‘I was clicked.’)”></div>

          在例二中,事件處理函數(shù)的大小寫可以任意

          1.       IE

          IE中,每個(gè)元素和window對(duì)象都有兩個(gè)方法:attachEvent()detachEvent()attachEvent()用來(lái)給一個(gè)事件附加事件處理函數(shù)。而detachEvent()用來(lái)將事件處理函數(shù)分離出來(lái)。Eg.

          var fnClick = function() {
                        alert(“Clicked
          !”);
                 }

                 
          var oDiv = document.getElementById(“div1”);
                 oDiv.attachEvent(“onclick”, fnClick);
                 oDiv.detachEvent(“onclick”, fnClick);

          2.       DOM

          DOM方法addEventListener()removeEventListener()用來(lái)分配和移除事件處理函數(shù)。與IE不同,這些方法需要三個(gè)參數(shù):事件名稱、要分配的函數(shù)和處理函數(shù)用于冒泡階段(為false時(shí))還是捕獲階段(為true時(shí))。Eg.

          oDiv. addEventListener (“onclick”, fnClick, false);

          oDiv.removeEventListener (“onclick”, fnClick, false);

          如果使用傳統(tǒng)方法直接給事件處理函數(shù)屬性賦值,事件處理函數(shù)將被添加到事件的冒泡階段,eg.

          oDiv.onclick = fnClick;

          oDiv.removeEventListener (“onclick”, fnClick, false);

           

          四.             事件對(duì)象

          事件對(duì)象只在發(fā)生事件時(shí)才被創(chuàng)建,且只有事件處理函數(shù)才能訪問(wèn)。所有事件處理函數(shù)執(zhí)行完畢后,事件對(duì)象就被銷毀。

          1.       定位

          IE中,事件對(duì)象是window對(duì)象的一個(gè)屬性event,也就是說(shuō),事件處理函數(shù)必須這樣訪問(wèn)事件對(duì)象:

          oDiv.onclick = function() {

                  var oEvent = window.event;

          }

          Event對(duì)象只能在事件發(fā)生時(shí)訪問(wèn)。所有的事件處理函數(shù)執(zhí)行完畢后,事件對(duì)象就被銷毀。

          2.       屬性/方法

          見(jiàn)頁(yè)面233-235頁(yè),在此不詳述。

          3.       相似性

          1) 獲取事件類型

          下面代碼可在任何瀏覽器中獲取事件的類型:

          var sType = oEvent.type;

          它返回“click”或“mouseover”之類的值。Eg.

          function handleEvent(oEvent) {
                        
          if (oEvent.type == “click”) {
                 alert(“Clicked
          !”);
          }
           else if (oEvent.type == “mouseover”) {
                 alert(“mouse over
          !”);
          }

          }

          oDiv.onclick 
          = handleEvent;
          oDiv.onmouseover 
          = handleEvent;

          2) 獲取按鍵代碼

          Eg. var iKeyCode = oEvent.keyCode;

          例如,Enter鍵的keyCode13,空格鍵的keyCode32,回退鍵為8.

          3) 檢測(cè)ShiftAltCtrl

          Eg.   var bShift = oEvent.shiftKey;

                  var bAlt = oEvent.altKey;

                  var bCtrl = oEvent.ctrlKey;

          4) 獲取客戶端坐標(biāo)

          Eg.  var iClientX = oEvent.clientX;

                  var iClientY = oEvent.clientY;

          5) 獲取屏幕坐標(biāo)

          可用screenXscreenY屬性來(lái)獲取鼠標(biāo)指針在計(jì)算機(jī)屏幕中的位置

          var iScreenX = oEvent.screenX;

          var iScreenY = oEvent.screenY;

          4.區(qū)別

          1)獲取目標(biāo)

           IE中:var oTarget = oEvent.srcElement;

           DOM兼容的瀏覽器中:var oTarger = oEvent.target;

          2)獲取字符代碼

          IE中:var iCharCode = oEvent.keyCode;

           DOM兼容的瀏覽器中:var iCharCode = oEvent.charCode;

          3)阻止某個(gè)事件的默認(rèn)行為

          IE中:oEvent.returnValue = false;

           DOM兼容的瀏覽器中:oEvent.preventDefault();

          4)阻止事件復(fù)制(冒泡)

          IE中:oEvent.cancelBubble = true;

           mozilla中:oEvent.stopPropagation ();

           

          五.事件的類型

          DOM標(biāo)準(zhǔn)定義了以下幾種事件:

                鼠標(biāo)事件
               
          鍵盤事件

                HTML事件:窗口發(fā)生變動(dòng)或者發(fā)生特定的客戶端-服務(wù)端交互時(shí)觸發(fā);

                突變事件:底層的DOM結(jié)構(gòu)發(fā)生改變時(shí)觸發(fā)。

          1.       鼠標(biāo)事件

          Eg. clickdbclickmousedownmouseoutmouseovermouseupmouseover

          1) 屬性

          Eg. 坐標(biāo)屬性(egclientXclientY等)、type屬性、targetsrcElement屬性、shiftKeyctrlKeyaltKeymetaKeyDOM)屬性、button屬性(只在mousedownmouseovermouseoutmouseovermouseup事件中)。

          2) 順序

          在同一個(gè)目標(biāo)上要按順序發(fā)生以下事件: mousedown->mouseup->click->mousedown->mouseup->click->dbclick

          2.       鍵盤事件

                 鍵盤事件有:keydownkeypresskeyup

          1) 事件的屬性

          對(duì)某個(gè)鍵盤事件,會(huì)填入如下的事件屬性: keyCodecharCode(僅DOM)、target(DOM)或者srcElementIE)、shiftKeyctrlKeyaltKeymetaKeyDOM)屬性。

          2) 順序

          按下一個(gè)字符鍵,發(fā)生事件順序?yàn)?/span>: keydown->keypress->keyup;

          按下一個(gè)非字符鍵,發(fā)生事件順序?yàn)?/span>:keydown->keyup

          3.       HTML事件

          HTML事件有: loadunloadaborterrorselectchangesubmitresetresizescrollfocusblur事件。

          1) loadunload事件

          eg. window.onload = function() {

                  alert(“loaded!”);

          }

          2) resize事件

          resize事件用來(lái)判斷何時(shí)動(dòng)態(tài)的改變某些元素。Eg.

          <body onresize=”alert(‘Resizing’)”>

          最大化或最小化窗口時(shí),也會(huì)觸發(fā)resize事件。

          3) Scroll事件

          Eg. <body onscroll=”alert(‘Scroll)”>

          4.變化事件

              變化事件包括如下內(nèi)容:

                 DOMSubtreeModified——當(dāng)文檔或者元素的子樹(shù)因?yàn)樘砑踊騽h除節(jié)點(diǎn)而改變時(shí)觸發(fā);

                 DOMNodeInserted——當(dāng)一個(gè)節(jié)點(diǎn)作為另一個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)插入時(shí)觸發(fā);

                 DOMNodeRemoved——當(dāng)一個(gè)節(jié)點(diǎn)作為另一個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)刪除時(shí)觸發(fā);

                 DOMNodeRemovedFromDocument——當(dāng)一個(gè)節(jié)點(diǎn)從文檔中刪除時(shí)觸發(fā);

                DOMNodeInsertedIntoDocument——當(dāng)一個(gè)節(jié)點(diǎn)插入到文檔中時(shí)觸發(fā)。

              這些事件的目的是,提供一個(gè)獨(dú)立于語(yǔ)言的事件范圍,使其可使用在所有基于XML的語(yǔ)言中。

           

          六.跨平臺(tái)的事件

          1. EventUtil對(duì)象

               var EventUtil = new Object;

          2. 添加/刪除事件處理函數(shù)

          EventUtil.addEventHandler = function() {
                  
          if (oTarget.addEventListener) //對(duì)DOM兼容的瀏覽器
                 oTarget.addEventListener(sEventType, fnHandler, false);
          }
           else if (oTarget.attachEvent) //對(duì)IE
                 oTarget.attachEvent("on" + sEventType, fnHandler);
          }
           else {
                 oTarget[
          "on" + sEventType] = fnHandler;
          }

          }


          EventUtil.removeHandler 
          = function(oTarget, sEventType, fnHandler) {
                  
          if (oTarget.removeEventListener) //對(duì)DOM兼容的瀏覽器
                         oTarget.removeEventListener(sEventType, fnHandler, false);
          }
           else if (oTarget.detachEvent) //對(duì)IE
                 oTarget.detachEvent("on" + sEventType, fnHandler);
          }
           else {
                 oTarget[
          "on" + sEventType] = null;
          }

          }

          3. 格式化event對(duì)象

               一種對(duì)付IEDOM中的event對(duì)象之間區(qū)別的最佳手段是,調(diào)整它們使之盡可能地表現(xiàn)相似,因?yàn)楦嗟臑g覽器使用的是DOM的事件類型,所以將IE的事件模型調(diào)整為接近于DOM事件模型就可以了。

              根據(jù)DOM屬性/方法與IE屬性/方法的不同,最后可得出如下的格式化event對(duì)象函數(shù),如下所示:

          EventUtil.formatEvent = function(oEvent) {
                  
          if (isIE && isWin) {
                 oEvent.charCode 
          = (oEvent.type == "keypress"? oEvent.keyCode : 0;
                 oEvent.eventPhase 
          = 2;
                 oEvent.isChar 
          = (oEvent.charCode > 0);
                 oEvent.pageX 
          = oEvent.clientX + document.body.scrollLeft;
                 oEvent.pageY 
          = oEvent.clientY + document.body.scrollTop;
                 oEvent.preventDefault 
          = function() {
                 
          this.returnValue = false;
          }
          ;

          if (oEvent.type == "mouseout"{
                 oEvent.relatedTarget 
          = oEvent.toElement;
          }
           else if (oEvent.type == "mouseover"{
                 oEvent.relatedTarget 
          = oEvent.fromElement;
          }

          oEvent.stopPropagation 
          = function() {
                 
          this.cancelBubble = true;
          }
          ;
          oEvent.target 
          = oEvent.srcElement;
          oEvent.time 
          = (new Date()).getTime();
          }

          return oEvent;
          }

          4. 獲取事件對(duì)象

                IEDOM使用不同的方法來(lái)獲取event對(duì)象。在IE中,event對(duì)象是與window對(duì)象相關(guān)的,而在DOM中,它獨(dú)立于任何其他對(duì)象,并且是作為參數(shù)傳遞的。下面我們編寫一個(gè)通用的獲取event對(duì)象的函數(shù),代碼如下:

          EventUtil.getEvent = function() {
                 
          if (window.event) {
                 
          return this.formatEvent(window.event);
          }
           else {
                 
          return EventUtil.getEvent.caller.arguments[0];
          }

          }

              調(diào)用舉例如下:

          oDiv.onclick = function() {
                  
          var oEvent = EventUtil.getEvent();
          }

          七.  小結(jié)

               本章詳細(xì)介紹了JavaScript中事件、事件流的概念,詳細(xì)研究了event對(duì)象,最后一節(jié)還創(chuàng)建了一個(gè)跨瀏覽器事件庫(kù),可使用同一套方法來(lái)訪問(wèn)事件對(duì)象,添加/刪除事件處理函數(shù),而無(wú)需考慮瀏覽器檢測(cè)的問(wèn)題。

          posted on 2007-08-27 09:17 阿蜜果 閱讀(3782) 評(píng)論(9)  編輯  收藏 所屬分類: Javascript


          FeedBack:
          # re: JavaScript學(xué)習(xí)筆記——事件(未完待續(xù))
          2007-08-27 09:58 | kafei
          恩,THX  回復(fù)  更多評(píng)論
            
          # re: JavaScript學(xué)習(xí)筆記——事件
          2007-09-20 11:37 | 162026094
          可惜無(wú)我要的內(nèi)容
            回復(fù)  更多評(píng)論
            
          # re: JavaScript學(xué)習(xí)筆記——事件
          2007-09-20 11:43 | 162026094
          我剛畢業(yè)進(jìn)公司搞開(kāi)發(fā),用的也JAVA JSP 什么的...很郁悶啊 主管要我做一些我完全不懂的東西 ,硬要我做出來(lái) ..........嗚嗚嗚嗚   回復(fù)  更多評(píng)論
            
          # re: JavaScript學(xué)習(xí)筆記——事件
          2007-09-20 12:53 | 阿蜜果
          跟主管好好溝通嘛,多向人家請(qǐng)教,東西都是學(xué)出來(lái)的  回復(fù)  更多評(píng)論
            
          # re: JavaScript學(xué)習(xí)筆記——事件
          2007-11-20 11:02 | Elance
          我剛學(xué)這個(gè)。。你的比記作的太好了。。我很想學(xué)到你所學(xué)的程度。。太想了  回復(fù)  更多評(píng)論
            
          # re: JavaScript學(xué)習(xí)筆記——事件
          2008-07-15 15:09 | lovemoon
          此文是你去年寫的了,確實(shí)比我那時(shí)強(qiáng)呀。
          你這段代碼有個(gè)缺陷:
          oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
          oEvent.pageY = oEvent.clientY + document.body.scrollTop;

          document.body.scrollLeft 標(biāo)準(zhǔn)模式下它始終為0.  回復(fù)  更多評(píng)論
            
          # re: JavaScript學(xué)習(xí)筆記——事件
          2009-05-15 00:26 | owenson
          謝樓主,看過(guò)了文章寫的很容易理解,轉(zhuǎn)走了。
            回復(fù)  更多評(píng)論
            
          # re: JavaScript學(xué)習(xí)筆記——事件[未登錄](méi)
          2009-07-01 11:02 | 小劉
          真的非常感謝!我的神啊!!!  回復(fù)  更多評(píng)論
            
          # re: JavaScript學(xué)習(xí)筆記——事件[未登錄](méi)
          2011-11-09 09:39 | 菜菜
          這篇文章對(duì)我很有用啊  回復(fù)  更多評(píng)論
            
          <2007年8月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

                生活將我們磨圓,是為了讓我們滾得更遠(yuǎn)——“圓”來(lái)如此。
                我的作品:
                玩轉(zhuǎn)Axure RP  (2015年12月出版)
                

                Power Designer系統(tǒng)分析與建模實(shí)戰(zhàn)  (2015年7月出版)
                
               Struts2+Hibernate3+Spring2   (2010年5月出版)
               

          留言簿(263)

          隨筆分類

          隨筆檔案

          文章分類

          相冊(cè)

          關(guān)注blog

          積分與排名

          • 積分 - 2298142
          • 排名 - 3

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 沁阳市| 湛江市| 精河县| 仁怀市| 峡江县| 手游| 无为县| 蓝田县| 开鲁县| 林甸县| 许昌县| 扶绥县| 佛坪县| 庆阳市| 渝北区| 镇远县| 普定县| 卢氏县| 瓦房店市| 宾阳县| 醴陵市| 海丰县| 长泰县| 石河子市| 东乡县| 财经| 万源市| 明光市| 嫩江县| 麻城市| 宜君县| 封丘县| 山西省| 陆河县| 湾仔区| 北辰区| 顺平县| 勃利县| 乌拉特后旗| 临潭县| 兴隆县|