天天看點

[轉載]超酷代碼-使用 ASP.NET AJAX 進行拖放

原文位址 http://msdn.microsoft.com/msdnmag/issues/08/01/WickedCode/default.aspx?loc=zh

在這三個下載下傳中,Futures 版本在開發人員社群最不受關注。這真讓人感到遺憾,因為 Futures 社群技術預覽 (CTP) 不僅提供了 ASP.NET AJAX 未來版本可能的樣子,同時還包含所有可用于建構當今最前沿的 Web 應用程式的功能。拖放就是一個相關例子。

Futures PreviewDragDrop.js 檔案隐含了對基于浏覽器的拖放型使用者界面提供豐富的支援。它所使用的模型是根據原先的 OLE 拖放模型設計的,其中由拖動源來實作 IDragSource 接口,由放置目标來實作 IDropTarget 接口,同時系統還提供了一個拖放管理器,将拖動源和放置目标連接配接起來。Futures 拖放管理器是一個 JavaScript 類的執行個體,名為 Sys.Preview.UI._DragDropManager,它會自動執行個體化并通過一個名為 Sys.Preview.UI.DragDropManager 的全局變量供使用。

近幾個月來,我一直打算編寫一個示例,說明如何使用 PreviewDragDrop.js 來實作真正的拖放,其特點是自定義拖動源和自定義放置目标。最後我終于完成了這項工作,結果也非常棒。在這個過程中我學到了很多關于 DragDropManager 的知識,包括如何通過添加對自定義拖動視覺效果的支援來增強它的功能。一旦您熟悉了該模型(并且了解了在 JavaScript 中派生類和實作接口的概念),DragDropManager 便為 Web 使用者界面的使用打開一個全新的世界。

在深入探讨代碼之前,請花一點時間下載下傳本文附帶的示例項目,然後快速運作一遍。請用 Visual Studio 的“打開網站”指令打開該示例,然後在浏覽器中檢視首頁 DragDropDemo.aspx。要運作這個示例,必須先安裝 ASP.NET AJAX Extensions。您無需下載下傳和安裝 Futures CTP,因為它已經在站點的 Bin 檔案夾中了。

您将在頁面頂部看到五個顔色樣本,在頁面底部看到一個标記為“Drop It Here(放置于此處)”的空白框(請參見圖 1)。顔色樣本是拖動源,空白框是放置目标。用滑鼠擷取其中一個顔色樣本,然後将其拖放到下面的框中。當光标進入框中時,請觀察框的顔色是如何從白色轉變為淺灰色的,這就是所謂的放置目标突出顯示功能。現在,将顔色樣本放入框中。框會變為與樣本相同的顔色。

[轉載]超酷代碼-使用 ASP.NET AJAX 進行拖放

Figure 1 DragDropDemo.aspx in Action (單擊該圖像獲得較小視圖)

[轉載]超酷代碼-使用 ASP.NET AJAX 進行拖放

Figure 1 DragDropDemo.aspx in Action (單擊該圖像獲得較大視圖)

擷取另一個顔色樣本,然後在螢幕上四處移動。注意,樣本隻能被放置在放置目标上,并且光标會指明此時是否可以放置樣本。同時還請注意,當拖動一個顔色樣本時,有一個樣本的半透明再現會随着光标移動,即“拖動視覺效果”,這樣您便知道自己拖動的是什麼。稍後您将看到,我們編寫代碼來建立拖動視覺效果,而 ASP.NET AJAX 則完成其餘的所有工作,包括讓拖動視覺效果與光标一起移動,以及随着每一次滑鼠移動更新光标。

驅動本頁面的自定義邏輯在一個名為 ColorDragDrop.js 的腳本檔案中,該檔案位于網站的 Scripts 檔案夾中。ColorDragDrop.js 是由 ScriptManager 加載的自定義腳本檔案。事實上,在源代碼視圖中打開 DragDropDemo.aspx 後即可看到 ScriptManager 加載了三個腳本檔案:PreviewScript.js,包含本示範使用的一個關鍵 ASP.NET AJAX 基類;PreviewDragDrop.js,包含 ColorDragDrop.js 使用的拖放支援;以及 ColorDragDrop.js 本身。

[轉載]超酷代碼-使用 ASP.NET AJAX 進行拖放

要用 ASP.NET AJAX 建構豐富的拖放型使用者界面,第一步是了解 Sys.Preview.UI._DragDropManager 類(以下簡稱 DragDropManager)。它實際上是根據主機浏覽器的類型,将大多數操作委托給 Sys.Preview.UI.IEDragDropManager 或 Sys.Preview.UI.GenericDragDropManager 的一個執行個體。它的公共接口由十幾個方法組成,其中三個在拖放實作中擔當了至關重要的角色:

startDragDrop——啟動拖放操作

registerDropTarget——将對象注冊為放置目标

unregisterDropTarget——登出放置目标

一旦 startDragDrop 方法被調用,DragDropManager 的主要工作就是監視目前的滑鼠事件、向光标下的拖動源和放置目标(如果有)發出相關通知,以及改變光标形狀以提供可視化訓示,表示在目前位置進行放置會發生什麼結果。為此,它會針對關鍵事件(如 mousemove 和 mouseup)注冊自己的處理程式。在這些事件處理程式中,它會在被拖動的源上調用 IDragSource 方法,并在下面任一個放置目标上調用 IDropTarget 方法。

例如,當攜帶負載的光标在放置目标邊界内移動時,DragDropManager 會調用拖動源的 get_dragDataType、get_dragMode 以及 getDragData 方法來擷取有關負載的資訊。然後它會将結果傳遞給放置目标的 canDrop 方法,以确定拖動源和放置目标是否相容。一旦發生放置,DragDropManager 會通過調用其 drop 方法來通知放置目标,并再次傳入從拖動源獲得的資料。

DragDropManager 可以确定光标是否位于放置目标上,因為它針對已注冊為放置目标的對象保留了一個引用的内部數組。通過調用 DragDropManager 的 registerDropTarget 方法可以将對象添加到該數組,調用 unregisterDropTarget 可将其删除。登出您所注冊的放置目标非常重要,這樣 DragDropManager 才能登出它代表那些放置目标注冊的相關事件處理程式。不這麼做會導緻記憶體洩漏。

DragDropManager 是連接配接拖動源和放置目标的粘合劑。沒有它,您将需要編寫大量代碼才能使拖放型使用者界面正常工作,當這些界面需要在各種浏覽器中工作時尤為如此。

[轉載]超酷代碼-使用 ASP.NET AJAX 進行拖放

在 JavaScript 中實作接口可能會讓人覺得奇怪,因為 JavaScript 并不顯式支援接口。是以,它也不顯式支援類、繼承、命名空間以及面向對象程式設計 (OOP) 的其他原則。但是,ASP.NET AJAX 的用戶端部分(即 Microsoft® AJAX Library)是一個完全以 JavaScript 實作的類庫。它采用流行的 JavaScript 程式設計技術來虛設 OOP,您可以用其建立自己的類,甚至可以在這些類中實作接口并從一個類派生另一個類。

ColorDragDrop.js 包含一對 JavaScript 類,名為 ColorDragSourceBehavior 和 ColorDropTargetBehavior。前者實作 IDragSource,兩者都屬于名為 Custom.UI 的命名空間。

要建立 Microsoft AJAX Library 風格的 JavaScript 類,首先需要定義與該類同名的函數。此函數将作為類構造函數:

然後,可以使用 JavaScript 原型屬性來定義要包含在該類的每個執行個體中的方法:

JavaScript 不支援強類型化或類型反射,是以 Microsoft AJAX Library 幫您實作了這一點。Type 類的方法(在 MicrosoftAjax.js 中,是 ASP.NET AJAX 核心的一部分),如 registerClass 和 registerNamespace,允許您注冊自己建構的類,并将它們配置設定給命名空間。之後,您可以使用諸如 getTypeName(由 Microsoft AJAX Library 添加到 JavaScript 的内置 Object 類型)等方法來反射您所注冊的類型。

Type 類提供的另一個基本基礎結構部分是從派生類的相應方法調用基類方法的機制。您可以從類構造函數調用 initializeBase 以調用基類的構造函數,以及從派生類中的方法覆寫調用 callBaseMethod 以調用基類中的等效方法。

ColorDragSourceBehavior 實作的大多數方法(get_dragDataType、getDragData 等)是 IDragSource 接口的成員。但 ColorDragSourceBehavior 實作了并非來自 IDragSource 的一些方法。例如,Initialize 方法為 mousedown 事件注冊處理程式,這樣拖動源通過調用 DragDropManager.startDragDrop 開始拖放操作。dispose 方法可登出事件處理程式,以避免記憶體洩漏。

IDragSource 方法本身十分簡單。get_dragDataType 會傳回字元串“DragDropColor”以辨別 ColorDragSourceBehavior 提供給放置目标的資料類型——在本例中為顔色資料。getDragData 會傳回一個字元串,定義拖動源所代表的顔色。get_dragMode 會傳回 Sys.Preview.UI.DragMode.Copy,指出如果此時進行放置,拖動源将是被複制而不是被移動。(另一個選擇是 Sys.Preview.UI.DragMode.Move,它與 Sys.Preview.UI.DragMode.Copy 一起在 PreviewDragDrop.js 中定義。)

ColorDragSourceBehavior 中需要注意的另一點是如何處理拖動視覺效果。mousedown 事件處理程式會通過對 DragDropManager 調用 startDragDrop 來啟動拖放操作。然而,在調用 startDragDrop 之前,該處理程式會調用 cloneNode 來克隆拖動源所代表的 DOM 元素。然後,它會将克隆節點的透明度設定為 40%,将節點插入浏覽器 DOM,并将新節點的引用傳遞給 DragDropManager,作為 startDragDrop 的一個參數。接着由 DragDropManager 來負責拖動視覺效果,即動态顯示它的移動以使其随光标移動。

[轉載]超酷代碼-使用 ASP.NET AJAX 進行拖放

ColorDropTargetBehavior 的 onDragEnterTarget 和 onDragLeaveTarget 方法可以實作先前示範的放置目标突出顯示。當攜帶負載的光标進入放置目标後,DragDropManager 就會調用 onDragEnterTarget。如果負載屬于正确的類型 (DragDropColor),onDragEnterTarget 就會将目标的目前背景色儲存在一個字段中,并将該背景色變為淺灰色。如果光标離開放置目标并仍攜帶負載,則 DragDropManager 會調用放置目标的 onDragLeaveTarget 方法。ColorDropTargetBehavior 對該方法的實作會将放置目标還原為其最初的背景色。

每當攜帶負載的光标在放置目标上移動時,DragDropManager 就會調用放置目标的 canDrop 方法以确定目标是否可以接受放置操作。ColorDropTargetBehavior.canDrop 檢查負載類型,如果它是 DragDropColor 則傳回 true,否則傳回 false。此過程使 DragDropManager 類可以通過光标向使用者提供必要的可視化回報。

發生放置操作時會調用放置目标的 drop 方法。ColorDropTargetBehavior.drop 方法從拖動源中提取顔色并相應地設定自己的背景色(實際上是作為放置目标的 DOM 元素的顔色)。

傳遞到 drop 方法的 dragMode 參數指定拖動模式,即移動或複制。最後将由放置目标根據拖動模式來處理浏覽器的 DOM。DragDropDemo.aspx 僅支援複制模式;是以放置目标會通過将其自身的背景色設定為拖動源中包含的顔色以達到“複制”這個拖動源的目的。如果同時還支援移動模式,放置目标将需要在成功完成放置後檢查拖動模式,如果 dragMode 已設定為 Sys.Preview.UI.DragMode.Move,則需要删除(或重定向)與該拖動源相關的 DOM 元素。

[轉載]超酷代碼-使用 ASP.NET AJAX 進行拖放

作為拖動源的顔色樣本無非是一些背景色設定為紅色、黃色、綠色等的 DIV。JavaScript pageLoad 函數會執行個體化五個 ColorDragSourceBehavior 對象并将每個對象配置設定給一個 DIV,進而将 DIV 轉換為拖動源。調用拖動源的初始化方法使每個拖動源都有機會注冊自己的 mousedown 事件處理程式。

放置目标也是 DIV。一個語句會執行個體化一個 ColorDropTargetBehavior 對象,并将其與 DIV 關聯,進而将 DIV 轉換為放置目标。另一個語句會調用 ColorDropTargetBehavior 的 initialize 方法,這樣它可以在 DragDropManager 中注冊為放置目标。

ColorDragSourceBehavior 和 ColorDropTargetBehavior 專門用于啟用要拖放的顔色。您可以建構類似它們的類來支援其他拖放情形。例如,如果您要建構一個照片共享站點,并希望允許使用者通過在檔案夾間拖動照片來對它們進行管理。您可以用 DIV 代表檔案夾,并編寫一個 PhotoDropTargetBehavior 類,将 DIV 轉換為放置目标。您可以相應地建立一個 PhotoDragSourceBehavior 類,将 DOM 圖像元素轉為可拖動的照片。雖然您建構的這些類都非常特定于應用程式,但它們都遵循本專欄中展示的拖動源和放置目标類所例舉的同一模式。

[轉載]超酷代碼-使用 ASP.NET AJAX 進行拖放

ASP.NET AJAX 是一個非常棒的工具,可向 Web 頁面添加 AJAX 的奇妙功能,而 ASP.NET AJAX Futures 版本則向核心平台添加了一些非常有用的增強功能。它對拖放型使用者界面的支援隻是其中一個例子;另外它還包含了動畫、用戶端資料綁定以及其他簡便的 DOM 抽象等等。不論這些功能是否會在某一天使之成為核心,它們現在都可供您使用。請考慮在您的下一個 ASP.NET AJAX 應用程式中使用這些功能吧,它們會讓您的應用程式變得更為出色。

繼續閱讀