在不同的瀏覽器上默認的拖拽能解決的問題相當少,所以有很多的框架都能實現這么個功能.使用拖拽行為能很好的改善用戶體驗,尤其是在購物的時候能讓用戶感到很新奇和體面.Script.aculo.us使用了三個類實現拖拽和排序,它們是Draggable,Droppable,Sortable.要實現一個完整的拖拽行為,需要Draggable,和Droppable的配合使用,由于這連個類的方法比較多,我只選取比較實用的幾個方法進行介紹.還是老規矩,先看看Demo:http://www1.qcxy.hb.cn/qphy/Script_Aculo_Us/DragDrop.html
Draggable
new Draggable("DraggableId"[,options])
主要選項
- snap:推拽的最小單位,默認為false,可以是數組或者函數,將這個屬性設置為[50,50],意味著最小的位移單位是50px,50px,如果設置為一個函數,這個函數的參數為(x,y),這個x,y指示當前的絕對坐標,函數應該返回二維數組,上面的例子中的Drag(UnAcceptable)推拽到頁面的左上角是就會"吸附"上去,就是因為函數的作用,詳細見源碼
- revert:推拽完畢之后是否回到原來的位置,默認為false,也可以是一個函數,這個函數必須返回true/false
- handle:"提手",移動整個塊的時候通常不需要在整個塊的區域都可以拖拽,比如移動一個欄目,通常只需要拖拽標題(比如Google的個性化主頁),將該屬性設置為標題的Id
- ghosting:推拽的過程中是否顯示"影子",默認為false
- constraint:限制能拖動的方向,默認的兩個方向都可以,可以設置為"vertical","horizontal"的任意
- zindex:"影子"的z-Index屬性
- scroll:拖拽出視圖范圍是否顯示自動滾動
- scrollSensitivity/scrollSpeed:默認值分為為20/15,控制滾動的敏感度和滾動速度
- delay:拖拽前的延時,開始拖拽后經過這個時間才"回過神來"
這里需要說明的是并非所有的標簽都支持該行為,詳細的情況請參閱官方文檔
API
- onStart:開始拖拽調用該函數,接受兩個參數(obj,oEvent)前者是$(DraggableId),后者是當前事件的event對象
- onDrag:在拖拽過程中反復的調用該函數,同樣接受兩個參數(obj,oEvent)
- change:在onDrag后調用,也會反復調用
- onEnd:拖拽行為結束調用,即鼠標彈起時激發
- destroy():該方法銷毀元素的拖拽行為
Droppables
Droppables(注意是復數形式)是一個抽象類,不能被實例化,只有一些靜態方法,常用的方法有add和move,分別增加可放置元素,和去除可放置元素
add方法:Dropables.add("ContainerId"[,options]),常用的選項
- accept: 數組或者字符串,表示該容器接受的元素的className的集合,默認的任何元素都接收
- hoverclass:當符合接受要求的元素拖至容器上時,其className
- onDrop():被拖拽的符合要求的元素在這里放置時調用該函數,接受三個參數(draggable,droppable,oEvent),draggable是被拖拽元素,droppable是被放置元素,oEvent當前事件對象
remove("ContainerId"),該方法去除容器的放置行為
(上面例子的源代碼)
Sortable
Sortable是一組可以通過拖拽交換位置的元素,可以先看看實例(
- ghosting:拖動時是否顯示"影子",默認為false
- constraint:允許的拖動方向,默認為兩個方向都可以,值為"horizontal","vertical"中的任一
- tag:能被拖動元素的標簽,默認為"li"
- hoverclass:拖動經過可以放置的位置是,可放置的元素的className
- dropOnEmpty:默認為false,是否在空的元素上放置
- handle/delayscroll/scrollSensitivity/scrollSpeed::同Draggable
- containment:數組,存放所有的放置元素的ID,參見實例的最后一個例子
- onUpdate():該方法接受參數$("ContainerId"),在拖動到可放置位置是調用該方法
- onChange():結束拖拽行為時調用該方法,接受參數element,表示被拖拽的元素
serialize(sortable)方法:該方法返回當前容器內元素的次序,但是要求子元素的id必須以"item_"開頭,且返回格式有講究,看下面的例子
<div id="horizontalSortable" class="item" style="margin-top:20px; height:40px;">
<div id="item_5">IE</div>
<div id="item_6">FireFox</div>
<div id="item_7">Safari</div>
<div id="item_8">Opera</div>
</div>
Sortable.create("horizontalSortable",
{
ghosting:true,
tag:'div',
constraint:'horizontal',
hoverclass:'hoverClass2'
});
Sortable.serialize('horizontalSortable')
//-->horizontalSortable[]=5&horizontalSortable[]=6&horizontalSortable[]=7&horizontalSortable[]=8
最后看一個例子,前面提到的containment選項在某些情況下很有用,比如要實現兩個容器里的元素可以互相交換子元素,即從一個容器拖至令一個容器中.來看下面的例子
<script type="text/javascript">
Sortable.create('sortUlLeft',{containment:['sortUlLeft','sortUlRight'], dropOnEmpty:true,ghosting:true,constraint:false,hoverclass:'hoverClass'});
Sortable.create('sortUlRight',{containment:['sortUlLeft','sortUlRight'], dropOnEmpty:true,ghosting:true,constraint:false,hoverclass:'hoverClass'});
</script>
上面的例子可以實現sortUlLeft,和sortUlRight的子元素互相交換