文章目錄
- Demo - Drag and Drop any item
- Demo - Drag and Drop any item
<base href="http://www.blueidea.com"><br /><fieldset id="Demo5" style="HEIGHT: 70px">Demo - Drag any of the<br />images<p></fieldset><p>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
你會注意到這個代碼幾乎是前面的全集,將前面的合在一起就實現了拖拽效果了.
當我們點擊一個item時,我們就擷取了很多變數,如滑鼠位置,滑鼠位置自然就包含了那個item的座標資訊了.如果我們點擊了一個20*20px映像的正中間,那麼滑鼠的相對座標為{x:10,y:10}.當我們點擊這個映像的左上方那麼滑鼠的相對座標為{x:0,y:0}.當我們點擊時,我們用這個方法取得一些滑鼠與圖片校對的資訊.如果我們不能載入頁面item,那麼資訊將是document資訊,會忽略了點擊的item資訊.
mouseOffset函數使用了另一個函數getPosition.getPosition的作用是返回item相對頁面左上方的座標,如果我們嘗試擷取item.offsetLeft或者item.style.left,那麼我們將取得item相對與父級的位置,不是整個document.所有的指令碼我們都是相對整個document,這樣會更好一些.
為了完成getPosition任務,必須迴圈取得item的父級,我們將載入內容到item的左/上的位置.我們需要管理想要的top與left列表.
自從定義了mousemove這個函數,mouseMove就會一直運行.第一我們確定item的style.position為absolute,第二我們移動item到前面定義好的位置.當mouse點擊被釋放,dragObject被設定為null,mouseMove將不在做任何事.
Dropping an Item
前面的例子目的很簡單,就是拖拽item到我們希望到的地方.我們經常還有其他目的如刪除item,比如我們可以將item拖到垃圾桶裡,或者其他頁面定義的位置.
很不幸,我們有一個很大的難題,當我們拖拽,item會在滑鼠之下,比如mouseove,mousedown,mouseup或者其他mouse action.如果我們拖拽一個item到垃圾桶上,滑鼠資訊還在item上,不在垃圾桶上.
怎麼解決這個問題呢?有幾個方法可以來解決.第一,這是以前比較推薦的,我們在移動滑鼠時item會跟隨滑鼠,並佔用了mouseover/mousemove等滑鼠事件,我們不這樣做,只是讓item跟隨著滑鼠,並不佔用mouseover等滑鼠事件,這樣會解決問題,但是這樣並不好看,我們還是希望item能直接跟在mouse下.
另一個選擇是不做item的拖拽.你可以改變滑鼠指標來顯示需要拖拽的item,然後放在滑鼠釋放的位置.這個解決方案,也是因為美學原因不予接受.
最後的解決方案是,我們並不去除拖拽效果.這種方法比前兩種繁雜許多,我們需要定義我們需要釋放目標的列表,當滑鼠釋放時,手工去檢查釋放的位置是否是在目標列表位置上,如果在,說明是釋放在目標位置上了. 複製代碼 代碼如下:/*
All code from the previous example is needed with the exception
of the mouseUp function which is replaced below
*/
var dropTargets = [];
function addDropTarget(dropTarget){
dropTargets.push(dropTarget);
}
function mouseUp(ev){
ev = ev || window.event;
var mousePos = mouseCoords(ev);
for(var i=0; i<dropTargets.length; i++){
var curTarget = dropTargets[i];
var targPos = getPosition(curTarget);
var targWidth = parseInt(curTarget.offsetWidth);
var targHeight = parseInt(curTarget.offsetHeight);
if(
(mousePos.x > targPos.x) &&
(mousePos.x < (targPos.x + targWidth)) &&
(mousePos.y > targPos.y) &&
(mousePos.y < (targPos.y + targHeight))){
// dragObject was dropped onto curTarget!
}
}
dragObject = null;
}
<base href="http://www.blueidea.com"><br /><fieldset id="Demo6" style="HEIGHT: 70px">Demo - Drag any image onto the<br />trashcan<p></fieldset><p>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
滑鼠釋放時會去取是否有drop屬性,如果存在,同時滑鼠指標還在drop的範圍內,執行drop操作.我們檢查滑鼠指標位置是否在目標範圍是用(mousePos.x>targetPos.x),而且還要符合條件(mousePos.x<(targPos.x + targWidth)).如果所有的條件符合,說明指標確實在範圍內,可以執行drop指令了.
Pulling It All Together
最後我們擁有了所有的drag/drop的指令碼片斷!下一個事情是我們將建立一個DOM處理.如果你不是很熟悉,請先閱讀我的JavaScript Primer on DOM Manipulation.
下面的代碼將建立container(容器),而且使任何一個需要drag/drop的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效果
檢查滑鼠是否沒有放開,如果沒有
設定curTarget代表當前item
記錄item的當前位置,如果需要的話,我們可以將它返回
複製當前的item到dragHelper中,我們可以移動帶陰影製作效果的item.
item拷貝到dragHelper後,原有的item還在滑鼠指標下,我們必須刪除掉dragObj,這樣指令碼起作用,dragObj被包含在一個容器中.
抓取容器中所有的item當前座標,高度/寬度,這樣只需要記錄一次,當item被drag時,每隨mouse移動,每移鐘就會記錄成千上萬次.
如果沒有,不需要做任何事,因為這不是一個需要移動的item
5、檢查curTarget,它應該包含一個被移動的item,如果存在,進行下面操作:
開始移動帶有陰影的item,這個item就是前文所建立的
檢查每個當前容器中的container,是否滑鼠已經移動到這些範圍內了
我們檢查看一下正在拖動的item是屬於哪個container
放置item在一個container的某一個item之前,或者整個container之後
確認item是可見的
如果滑鼠不在container中,確認item是不可見了.
6、剩下的事就是捕捉mouseUp的事件了 <base href="http://www.blueidea.com"><br /><style>LI { MARGIN-BOTTOM: 10px } OL { MARGIN-TOP: 5px } .DragContainer { BORDER-RIGHT: #669999 2px solid; PADDING-RIGHT: 5px; BORDER-TOP: #669999 2px solid; PADDING-LEFT: 5px; FLOAT: left; PADDING-BOTTOM: 0px; MARGIN: 3px; BORDER-LEFT: #669999 2px solid; WIDTH: 100px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 2px solid } .OverDragContainer { BORDER-RIGHT: #669999 2px solid; PADDING-RIGHT: 5px; BORDER-TOP: #669999 2px solid; PADDING-LEFT: 5px; FLOAT: left; PADDING-BOTTOM: 0px; MARGIN: 3px; BORDER-LEFT: #669999 2px solid; WIDTH: 100px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 2px solid } .OverDragContainer { BACKGROUND-COLOR: #eee } .DragBox { BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee } .OverDragBox { BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee } .DragDragBox { BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee } .miniDragBox { BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee } .OverDragBox { BACKGROUND-COLOR: #ffff99 } .DragDragBox { BACKGROUND-COLOR: #ffff99 } .DragDragBox { FILTER: alpha(opacity=50); BACKGROUND-COLOR: #ff99cc } LEGEND { FONT-WEIGHT: bold; FONT-SIZE: 12px; COLOR: #666699; FONT-FAMILY: verdana, tahoma, arial } FIELDSET { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px } .History { FONT-SIZE: 10px; OVERFLOW: auto; WIDTH: 100%; FONT-FAMILY: verdana, tahoma, arial; HEIGHT: 82px } #DragContainer8 { BORDER-RIGHT: #669999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #669999 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 0px; BORDER-LEFT: #669999 1px solid; WIDTH: 110px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 1px solid; HEIGHT: 110px } .miniDragBox { FLOAT: left; MARGIN: 0px 5px 5px 0px; WIDTH: 20px; HEIGHT: 20px } pre{border:1 solid #CCC;background-color:#F8F8F0;padding:10px;} </style><p><!--the mouse over and dragging class are defined on each item-->Item #1Item #2Item #3Item #4Item #5Item #6Item #7Item #8Item #9Item #10Item #11Item #12<p><input onclick="runEx('runcode40343')" type="button" value="運行代碼"><input onclick="doCopy('runcode40343')" type="button" value="複製代碼"><input onclick="doSave(runcode40343)" type="button" value="儲存代碼">[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]<p><p>你現在擁有了拖拽的所有東西.</p><p>下面的三個demo是記錄事件曆史.當你的滑鼠在item上移動,將記錄所生的事件,如果你不明白可以嘗試一下滑鼠的划過或者拖動,看有什麼發生.<textarea id="runcode79864"><base href="http://www.blueidea.com"><br /><style type="text/css">LI { MARGIN-BOTTOM: 10px } OL { MARGIN-TOP: 5px } .DragContainer { BORDER-RIGHT: #669999 2px solid; PADDING-RIGHT: 5px; BORDER-TOP: #669999 2px solid; PADDING-LEFT: 5px; FLOAT: left; PADDING-BOTTOM: 0px; MARGIN: 3px; BORDER-LEFT: #669999 2px solid; WIDTH: 100px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 2px solid } .OverDragContainer { BORDER-RIGHT: #669999 2px solid; PADDING-RIGHT: 5px; BORDER-TOP: #669999 2px solid; PADDING-LEFT: 5px; FLOAT: left; PADDING-BOTTOM: 0px; MARGIN: 3px; BORDER-LEFT: #669999 2px solid; WIDTH: 100px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 2px solid } .OverDragContainer { BACKGROUND-COLOR: #eee } .DragBox { BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee } .OverDragBox { BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee } .DragDragBox { BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee } .miniDragBox { BORDER-RIGHT: #000 1px solid; PADDING-RIGHT: 2px; BORDER-TOP: #000 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; MARGIN-BOTTOM: 5px; PADDING-BOTTOM: 2px; BORDER-LEFT: #000 1px solid; WIDTH: 94px; CURSOR: pointer; PADDING-TOP: 2px; BORDER-BOTTOM: #000 1px solid; FONT-FAMILY: verdana, tahoma, arial; BACKGROUND-COLOR: #eee } .OverDragBox { BACKGROUND-COLOR: #ffff99 } .DragDragBox { BACKGROUND-COLOR: #ffff99 } .DragDragBox { FILTER: alpha(opacity=50); BACKGROUND-COLOR: #ff99cc } LEGEND { FONT-WEIGHT: bold; FONT-SIZE: 12px; COLOR: #666699; FONT-FAMILY: verdana, tahoma, arial } FIELDSET { PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px } .History { FONT-SIZE: 10px; OVERFLOW: auto; WIDTH: 100%; FONT-FAMILY: verdana, tahoma, arial; HEIGHT: 82px } #DragContainer8 { BORDER-RIGHT: #669999 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: #669999 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 0px; BORDER-LEFT: #669999 1px solid; WIDTH: 110px; PADDING-TOP: 5px; BORDER-BOTTOM: #669999 1px solid; HEIGHT: 110px } .miniDragBox { FLOAT: left; MARGIN: 0px 5px 5px 0px; WIDTH: 20px; HEIGHT: 20px } PRE { BORDER-RIGHT: #ccc 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #ccc 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #ccc 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #ccc 1px solid; BACKGROUND-COLOR: #f8f8f0 } </style><fieldset id="Demo0">Demo - Drag and Drop any itemItem #1Item #2Item #3Item #4Item #5Item #6Item #7Item #8Item #9Item #10Item #11Item #12<fieldset><legend>History</legend></fieldset></fieldset><fieldset id="Demo7"><legend>Demo - Drag and Drop any item</legend><ol id="DragContainer7" history="History1"><li id="ListItem1">Item #1 </li><li id="ListItem2">Item #2 </li><li id="ListItem3">Item #3 </li><li id="ListItem4">Item #4 </li><li id="ListItem5">Item #5 </li></ol></fieldset><fieldset id="Demo8">Demo - Drag and Drop any item12345678910111213141516</fieldset><p>