Javascript 中的事件綁定__Java

來源:互聯網
上載者:User

為組件提供事件處理入口,可以極大的提高組件的封閉性,同時又能讓組件很好的和外界通訊。並且這也是我們已經習慣使用的一種開發模式,.NET、DHTML等都提供了一套完整的事件處理模型。下面是關於使用DHTML中事件的一個總結。

    
DHTML提供了3種事件的使用方式,它們分別是:
    
1、Inline HTML: <ELEMENT onXXX='handler'></ELEMENT>
    
這是最簡單最常用的事件綁定方式,不過這裡onXXX的值為handler是不太確切的說法。其實這個handler的位置可以放置任何合法的JavaScript語句,因為IE在產生DHMTL樹時會為當前Element構建一個'匿名'成員方法,onXXX指向這個方法的handler。比如我們寫下,<element id='elmt' onXXX='var abc =0; for ( var i=0 ; i < 100 ; i++ ) abc+=i;'></element>,實際上在DHMTL樹種存在如下代碼結構:
function anonymous(){    var abc =0; for ( var i=0 ; i < 100 ; i++ ) abc+=i;}

此時anonymous方法中的this就是elmt對象。


2、Event property: object.onXXX = handler

這個使用方法是把函數名(handler)賦予element預定義的事件屬性上(onXXX)。這裡需要注意兩個問題:

一是,我們在使用object.onXXX = handler是需要保證object已經在頁面中產生。比如我們為document.body賦予事件處理函數,我們必須保證document.body已經存在,就是說我們不能在<body>之前在的全域語句中使用document.body;

二是,handler必須是函數名,和使用方法1中的handler可以是任何JavaScript語句不同。我們最容易出錯的使用是,當我們習慣了在inline html中使用<element id='elmt' onXXX = 'return false'></element>後,如果這樣使用elmt.onXXX='return false;'。那麼就歇菜了,不會有任何執行效果,當然IE也不報錯。正確的使用是:
elmt.onXXX = function() { return false; }


3、Named Script: <SCRIPT FOR = object EVENT = onclick>

IE獨家支援,沒有怎麼使用過,不覺得有什麼特別的地方哈。如果您知道它的妙處願聞其詳。

DOM提供了兩種事件處理使用,它們分別是:
    
1、attachEvent method:
    使用方法:bSuccess = object.attachEvent(sEvent, fpNotify)。解釋就抄msdn了
    Parameters
       sEvent Required. String that specifies any of the standard DHTML Events. 
       fpNotify Required. Pointer that specifies the function to call when sEvent fires. 
    Return Value
         Boolean. Returns one of the following possible values:        true The function was bound successfully to the event. 
       false The function was not bound to the event. 
    DOM提供的這個事件附加方式實際上是一個集合操作,我們可以多次的向同一個事件簽名上attach多個事件處理函數,比如:
window.attachEvent('onload', handler1);window.attachEvent('onload', handler2);window.attachEvent('onload', handler3);window.attachEvent('onload', handlerN);

將會執行這個N個handler,但是不保證執行順序。這裡有個例外,attachEvent在document.body上attach事件'onload'沒有效果,但是attch window對象的'onload'是正確的。根據頁面初始化順序來看,及document.body.attachEvent('onload', handler)返回true來看,這因該是IE的一個bug。

注意DHTML的Event Property方式和DOM的attachEvent方式的區別:

Event Property方式,當觸發事件時,事件處理函數是一個無參數函數,我們只能通過event這個window的屬性來讀取和事件相關的資訊。attachEvent方式,當事件處理函數被觸發時,該函數的第一個參數arguments[0],預設是該視窗上的event。什麼意思呢。不明白參看這裡。   ---------------------------------------------補充的部分----------------------------------------------------- JavaScript對象的引用
為了減少JavaScript對象的下載次數,Tasian只會在瀏覽器第一次請求應用時才會下載JavaScript檔案。JavaScript對象只會駐留在Top級表單,任何其它表單需要引用到該JavaScript對象,只需要在引如下的方式進行引用就行:

需要引用的表單Button = top.Button //參閱MscrRouter.js

而Button真正定義的JavaScript檔案處於Top表單,為了保證定義的對象格式能跨瀏覽器有效,Tasian使用了如下的格式進行對象定義:
//定義對象名
function MscrButton()
{
};
//定義對象的方法
MscrButton.onClick = function(strWin, strName)
{
MscrSystem.setAction(strWin, strName, "click", ""); 
};

請注意,在每個函數後面都有一個分號,這一點對於Tasian非常的重要。因為Tasian中所使用的JavaScript檔案都是經過壓縮的,並且將全域的JavaScript對象定義合成在一個JavaScript檔案中。它的好處是減少網路流量、減少JavaScript對象對用戶端資源的佔用及減少對伺服器請求的發送。

2. 遮罩運用
遮罩是指在一個對象上放置一個新的對象,新對象便是遮罩層。它能截獲所有被遮罩對象的事件。

Tasian 所有的表單都是在一個Iframe, 對於表單拖動,在IE中能容易地進行事件捕捉處理,可以在非IE的瀏覽器中,當Mouse移到Iframe時,該 Iframe將會最先處理該事件,使得對Iframe的拖動無效。所以Tasian會在Iframe上加上一個可以關開的遮罩層DIV元素,當要進行表單對象拖動時,該層會開啟,當拖動完成後,該層會關閉。

3. 模態表單Tasian有一個特殊的表單,只有當它關閉時才能操作其它表單內容。該表單叫模態表單。在JavaScript實現類比表單時,也是使用了一個DIV層,使得它始終於模態表單的下一級,這樣它就能截獲所有對它父表單的操作事件。

4. 動態事件綁定
在IE在動態事件綁定是通過attachEvent實現的,而在Mozilla系列是使用addEventListener。以下是代碼摘自document.js兩者的使用方法
if (top.isIE)
{
oDB.setCapture();
oDB.attachEvent("onmousemove", __resizingMe);
oDB.attachEvent("onmouseup", __endResizeMe);
}
else
{
document.captureEvents(Event.MOUSEEVENT | Event.MOUSEUP); 
document.addEventListener("mousemove", __resizingMe, false);
document.addEventListener("mouseup", __endResizeMe, false);
}

….
if (top.isIE)
{
oDB.detachEvent("onmousemove", __resizingMe);
oDB.detachEvent("onmouseup", __endResizeMe);
oDB.releaseCapture();

}
else
{
document.releaseEvents(Event.MOUSEMOVE | Event.MOUSEUP);
document.removeEventListener("mousemove", __resizingMe, false);
document.removeEventListener("mouseup", __endResizeMe, false);
}

5. Style對象
對於IE中HTML元素的Style對象其強大之處大家都瞭解,可是對於Mozilla中HTML的Style對象由於其相關介紹實在太少,所以大家都對它很陌生。其實Mozilla中的Style仍然很強大,IE能完成的功能,它大都能完成,只不過大家不瞭解罷了。比如IE中有filter屬性用來設定漸近色,而Mozilla中可以用alpha實現。

以下代碼摘自MscrSystem.js
if (!isIE)
{

oEnMsk.style.filter = "alpha(opacity = 35)";
oEnMsk.style.MozOpacity = 0.35;

}
else
{
var strHTML = "
strHTML += ">";

oObj.parentNode.insertAdjacentHTML("BeforeEnd", strHTML);
}

當然Mozilla的Style屬性遠不止如此,它還可以設定DIV的外觀:圓形、鬱圓形等。 -----------------------------------------------------------------增加的部分----------------------------------- IE下與firefox下,javascript的事件Binder 方法有所不同,以下是兩個瀏覽下的區別,以滑鼠點擊事件為例:

在IE下,事件為onclick,綁定時為obj.attachEvent("eventName", functionName, useCapture);在此例中eventName為click,functionName為要調用的事件處理方法,比如a()。useCapture表示事件處理模式是否使用捕獲模式,即從外向內的模式。那麼整條語句應為obj.attachEvent("onclick", a, false); 
在firefox下,事件為click,綁定時為obj.addEventListener("eventName", functionName, useCapture);相應的語句為obj.addEventListener("click", functionName, useCapture);
在應用時,為了相容性,可以使用以下判斷來綁定事件:

 if (window.attachEvent)
 {//window下的事件綁定}
  else{//firefox下的事件綁定} _--------------------------------------------------------j最後的補充---------------------------------------

今天暫時拋開prototype1.3.1,分享一下我的javscript事件設計心得。其實現的技術基礎在於函數的本質,這在前面兩篇中有詳細敘述。

javascript內建的對象都有事件功能,比如button就有onclick事件,input就有onchange事件。那麼如何在我們自訂的類中實現事件呢。很簡單:
var  myClass = Class . create ();
myClass . prototype ={
  show : function (){
   //statement

   onshow ();
  },
  onshow : function (){}
}

這段代碼其實就是實現了onshow事件,在myClass執行個體show的時候觸發,你可以給onshow綁定一個函數,從而使用事件功能。在javascript中,內建的對象事件使用方法都是如此,其內部實現應該也是基於這樣的模式。但是,這樣的實現卻有兩個突出的問題:
1.只能綁定一個回呼函數。如果要實現多綁定,必須自己寫很多代碼來封裝要回調的函數到一個函數中。
2.不能傳遞參數。因為onshow只能賦給函數名,即函數體本身,並不能傳遞參數進去,為了傳遞參數,我曾寫過一篇:《用外殼封裝法給javascript觸發器傳遞參數》,可見,同樣需要寫很多代碼。

那麼,這些問題怎麼解決呢。javascript內建對象的事件使用我們就暫時不管,來考慮一下怎麼在自己實現的類中避免如上兩個問題。實現之前,先來考慮下面這個問題,或許有助於理解實現這個功能的意義:

我的頁面需要用javascript進行一些初始化,但初始化必須在頁面載入完成之後進行。通常我們會將代碼放到html檔案最下面。但此時,在頁面載入完成之前,頁面上的按鈕點擊需要調用必須經過初始化的方法,如果不作判斷,那麼就很容易出現指令碼錯誤。因為還沒有初始化,一個簡單的想法是:用一個bool變數loaded來判斷,初始為false,初始化完成後為true,那麼按鈕點擊時遇到false就簡單返回。這實現固然簡單,但有可能造成使用者發現點擊無效,而不知其所以然。所以完善的做法應該是能捕獲這個方法,將其綁定到頁面載入完成事件上,當頁面載入完成後自動調用。

好,現在看事件設計模式的實現代碼:
var  myClass = Class . create ();
myClass . prototype ={
  initialize : function (){
   this . initEvent = new  Object ();
  },
  init : function (){
   //初始化要執行的語句
  
   //下面是調用綁定的回呼函數
   for ( var  p  in  this . initEvent ){
    //extend是內建方法,不可作為回調關鍵字
    if ( p == "extend" ) continue ;
    this . initEvent [ p ]. apply ( _object ,[]);
   }
  },
  attachOnInit : function ( _key , _object , _method , _arguments ){
   this . initEvent [ _key ]= createFunction ( _object , _method , _arguments );
  },
}

function  createFunction ( _object , _method , _arguments ){
  return  function (){
   _method . apply ( _object , _arguments );
  }
}

這段代碼就實現了一個類myClass,具有init方法,觸發oninit事件,使用時要想綁定一個事件,可以調用attachOnInit方法,參數的意思分別為:_key,回調參函數的唯一標識,如果重複,後者覆蓋前者;_object回呼函數的對象,如果是直接在script中的函數,可以傳遞this指標進去,即document對象;_method,要回調的函數,注意,這是一個函數名,不是字串;_arguments,回呼函數的參數數組。還有一個函數是createFunction,作用是封裝一個函數,使其內建參數,這是外殼封裝法那篇文章的一個通用實現。如果大家看過ajax之旅系列的前兩篇文章,應該容易理解上面的代碼,如果有什麼問題,歡迎評論。

使用樣本:
function  myFunc ( s ){
  alert ( s );
}
var  myObj = new  myClass ();
myClass . attach ( "key1" , this , myFunc ,[ 123 ]);
myClass . init ();


這就將myFunc函數綁定到myObj的init函數,執行後會彈出對話方塊123

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.