2007年10月27日 星期六

用 JavaScript 實現滑鼠拖拽網頁表單 ﹙四﹚

Pulling It All Together

  最後我們擁有了所有的 drag/drop 的腳本片斷!下一個事情是我們將創建一個 DOM 處理。如果你不是很熟悉,請先閱讀我的 JavaScript Primer on DOM Manipulation

  下面的代碼將創建 container(容器),而且使任何一個需要 drag/dro p的 item 變成一個容器的 item。代碼在這個文章第二個 demo 的後面,它可以用戶記錄一個 list(清單),定為一個導航窗口在左邊或者右邊,或者更多的函數你可以想到的。

  下一步我們將透過 "假代碼" 讓 reader 看到真代碼,下面為推薦︰

  1、當document第一次載入時,創建 dragHelper DIV.dragHelper 將給移動的 item 加陰影。真實的 item 沒有被 dragged,只是用了 insertBefor 和 appendChild 來移動了,我們隱藏了 dragHelper。

  2、有了 mouseDown 與 mouseUp 函數。所有的操作會對應到當到 iMouseDown 的狀態中,只有當 mouse 左鍵為按下時 iMouseDown 才為真,否則為假。

  3、我們創建了全局變量 DragDrops 與全局函數 CreateDragContainer.DragDrops 包含了一系列相對彼此的容器。任何參數 (containers) 將透過 CreatedcragContainer 進行重組與序列化,這樣可以自由的移動。CreateDragContainer 函數也將 item 進行綁定與設定屬性。

  4、現在我們的代碼知道每個 item 的加入,當我們移動處 mouseMove,mouseMove 函數首先會設定變量 target,滑鼠移動在上面的 item,如果這個 item 在容器中 (checked with getAttribute)︰

 * 運行一小段代碼來改變目標的樣式。創造 rollover 效果。
 * 檢查滑鼠是否沒有放開,如果沒有︰
  o 設定 curTarget 代表目前 item。
  o 記錄 item 的目前位置,如果需要的話,我們可以將它返回。
  o 克隆目前的 item 到 dragHelper 中,我們可以移動帶陰影效果的 item。
  o item 拷貝到 dragHelper 後,原有的 item 還在滑鼠指針下,我們必須刪除掉 dragObj,這樣腳本起作用,dragObj 被包含在一個容器中。
  o 抓取容器中所有的 item 目前坐標,高度/寬度,這樣隻需要記錄一次,當 item 被 drag 時,每隨 mouse 移動,每移鐘就會記錄成千上萬次。
 * 如果沒有,不需要做任何事,因為這不是一個需要移動的 item。

  5、檢查 curTarget,它應該包含一個被移動的 item,如果存在,進行下面操作:

 * 開始移動帶有陰影的 item,這個 item 就是前文所創建的。
 * 檢查每個目前容器中的container,是否滑鼠已經移動到這些範圍內了。
  o 我們檢查看一下正在拖曳的 item 是屬於哪個 container。
  o 放置 item 在一個 container 的某一個 item 之前,或者整個 container 之後。
  o 確認 item 是可見的。
 * 如果滑鼠不在 container 中,確認 item 是不可見了。

  6、剩下的事就是捕捉 mouseUp 的事件了。

實現一個拖曳的全代碼:



  你現在擁有了拖拽的所有東西。

  下面的三個 demo 是記錄事件歷史。當你的滑鼠在 item 上移動,將記錄所生的事件,如果你不明白可以嘗試一下滑鼠的劃過或者拖曳,看有什麼發生。

  觀看範例

用 JavaScript 實現滑鼠拖拽網頁表單 ﹙一﹚
用 JavaScript 實現滑鼠拖拽網頁表單 ﹙二﹚
用 JavaScript 實現滑鼠拖拽網頁表單 ﹙三﹚
用 JavaScript 實現滑鼠拖拽網頁表單 ﹙四﹚





今天因為要寫關於 JavaScript 捕捉滑鼠位置的程式,很意外的被我找到這篇文章,常常在很多網站看到大家用這樣的技術來做版面編排,但是都苦無方法來研究,看到了這篇文章讓我欣喜若狂,所以我擅自轉貼到我的筆記上,再找時間好好研究研究,為尊重原作者做以下申明︰
原文︰How to Drag and Drop in JavaScript
作者︰Mark Kahn
譯者︰雪山老人
所有本文及範例檔案相關版權為以上作者所有。

3 則留言:

匿名 提到...

lan大大您好:
看到這個文章相當高興,不過我個人還是有時用上的問題,可否幫我解喲?

遊戲:
一個小九宮內有1~9的數字,分布在九個小方格內,將數字隱藏起來。
小九宮上方有數字1~9,用滑鼠拖曳其中一個數字到小九宮中,
設定當onmouseup事件發生時,比對「被拖曳的數字」與事件發生時,
「滑鼠所在小方格位置內數字」,若相符則顯示小方格中的數字,
若不相符則顯示錯誤訊息。

問題:
當onmouseup事件發生時,因為滑鼠事件停留在「被拖曳數字」上,
所以無法判斷(獲得)滑鼠所在小方格位置,進而取值,有點頭痛?

PS.我是用
cell = event.srcElement.cellIndex; // 讀取行的位置
row = event.srcElement.parentElement.rowIndex; // 讀取列的位置
方式獲取滑鼠所在小方格位置(沒有用座標方式),進而轉換該位置方陣值。

Ian 懶惰蟲 提到...

用 JavaScript 實現滑鼠拖拽網頁表單 ﹙三﹚ 中有提到,當 mouseup 時我們檢查滑鼠位置是否在目標範圍內,而判斷式應該為︰

if( (mousePos.x > itemPos.x) &&
(mousePos.x < (itemPos.x + item.offsetWidth)) &&
(mousePos.y > itemPos.y) &&
(mousePos.y < (itemPos.y + item.offsetHeight)) ){
//在目標範圍內
}else{
//不在目標範圍內
}

net538 就你的問題,必須自己判斷滑鼠位置是否在目標範圍內,這裡我寫了一個簡單的範例讓你參考,觀看範例

net538 提到...

您寫程式的方式真是棒極了,且花了這麼多的時間為我解析,並寫成範例程式,真是太感動了,謝謝您。

我剛學javascript約3個月,因為想寫一個網頁用數獨遊戲才學的,想不到javascript的運用還真有點難懂!

請問您是否有時間幫我檢視我的程式語法及運作呢?若有空,需要多少錢呢?因為我真的無法再繼續寫下去了。

哈哈!再次感謝您的回應,謝謝!