要求
拖曳排序,從名字就不難想像,就是按住一行資料拖曳到想要的排序位置,儲存新的排序佇列。
思路
先給清單行建立錨點,綁定mousedown和mouseup事件,當滑鼠移動到想要插入的位置時,將物件行移到目標行,然後對其經過的所有行進行排序處理。
思路很簡單,但這裡面還是有幾個問題要注意
1、移動到什麼位置可以視為要插入到目標行的位置。
2、移動出了頂端和底端時,判斷為第一和最後。
3、向上移動和向下移動的處理
解決
關於事件
Javascript裡滑鼠按下和放開事件為onmousedown,onmouseup,JQuery裡是mousedown,mouseup,所以,這裡使用mousedown和mouseup
首先,要知道介面有多少行,每一行有多高,因為要判斷滑鼠的移動距離
之所有要取lineNum(行數),除了計算行高外,還有個目的是要使用index(),透過序列索引值來進行移動行到目標位置
topDistance=thisIndex*lineHeight; //該行距離第一行頂端的距離
downDistance=(lineNum-thisIndex-1)*lineHeight; //該行距離最後一行底端的距離
thisLineTop,主要是用來和滑鼠移動位置進行高度計算,然後根據行高、索引值來判斷是移動到哪一行了。還有個作用是用來確定是否按在了移動錨點上,如果有值,說明是,那後面的mouseup就是成立的,如果沒有值,說明沒有按到錨點上,mouseup不執行任何操作。為什麼要這樣做呢?因為不管在頁面的什麼位置點滑鼠,都會觸發mouseup事件,如果沒有一個判斷,就會不停的執行,就會產生一些問題。
$("#dgf").css({"left":e. pageX setting.tipsOffsetLeft 'px',"top":e.pageY 'px'});
});
取消禁止選擇
好了,下面是mouseup事件。這裡mouseup事件是綁定在body上的,因為mouseup如果只是綁定在錨點上,那麼當滑鼠移出錨點的時候,再放開滑鼠,會發現,這個mouseup事件不執行了,因為它會認為是別的物件的mouseup。所以,最保險的方法是用$('body').mouseup。這樣基本上就不會有問題。
mouseup觸發後,首先就要判斷thisLineTop是不是有值,防止無意義的事件執行。跟著判斷滑鼠移動的距離是正還是負,也就是向上移動還是向下移動。
var moveDistance=e.pageY-thisLineTop;
依不同的方向作不同的處理
複製程式碼
複製程式碼
var dgid='',thisIndex,thisLineTop=0,topDistance,downDistance;
var tbodyHeight=setting.frame.outerHeight();
var lineNum=$("."+setting.dgLine).length;
var lineHeight=Math.ceil(tbodyHeight/lineNum);
$("."+setting.dgButton).mousedown(function(e){
dgid=$(this).attr(setting.id);
thisIndex=$("#"+setting.linePre+dgid).index();
var left=e.pageX+20;
var top=e.pageY;
thisLineTop=$("#"+setting.linePre+dgid).offset().top;
topDistance=thisIndex*lineHeight;
downDistance=(lineNum-thisIndex-1)*lineHeight;
$("#"+setting.linePre+dgid).css('background',setting.lineHighlight);
dg_tips(left,top);
$('body').css('cursor','move');
unselect();
setting.frame.mousemove(function(e){
$("#dgf").css({"left":e.pageX+setting.tipsOffsetLeft+'px',"top":e.pageY+'px'});
});
});
$('body').mouseup(function(e){
if(thisLineTop>0){
var moveDistance=e.pageY-thisLineTop;
if(moveDistance<0){
if(thisIndex!=0){
moveDistance=Math.abs(moveDistance);
if(moveDistance>lineHeight/2){
if(moveDistance>topDistance){
focusIndex=0;
}else{
focusIndex=thisIndex-Math.ceil(moveDistance/lineHeight);
}
$("."+setting.dgLine).eq(focusIndex).before($("#"+setting.linePre+dgid));
dg_update(thisIndex,focusIndex);
}
}
}else{
if(thisIndex!=lineNum-1){
if(moveDistance>lineHeight/2+lineHeight){
if(moveDistance>downDistance){
focusIndex=lineNum-1;
}else{
focusIndex=thisIndex+Math.ceil(moveDistance/lineHeight)-1;
}
$("."+setting.dgLine).eq(focusIndex).after($("#"+setting.linePre+dgid));
dg_update(thisIndex,focusIndex);
}
}
}
$("#dgf").remove();
$("#"+setting.linePre+dgid).css('background','');
dgid='';
thisLineTop=0;
$('body').css('cursor','default');
onselect();
}
});
function dg_update(thisIndex,focusIndex){
dg_mask();
var start=thisIndex
for(var i=start;i<=end;i++){
ids+=i==start?$("."+setting.dgLine).eq(i).attr(setting.id):','+$("."+setting.dgLine).eq(i).attr(setting.id);
vals+=i==start?i:','+i;
}
$.getJSON(setting.JSONUrl,{'do':'changeorders','ids':ids,'vals':vals},function(d){
$("#dg_mask").remove();
});
}
function dg_mask(){
var W=setting.frame.outerWidth();
var H=setting.frame.outerHeight();
var top=setting.frame.offset().top;
var left=setting.frame.offset().left;
var mask="
$('body').append(mask);
$("#dg_mask").css({"background":"#999","position":'absolute',' width':W 'px','height':H 'px','line-height':H 'px','top':top 'px','left':left 'px','filter': 'alpha(opacity='setting.maskOpacity')','moz-opacity':setting.maskOpacity/100,'opacity':setting.maskOpacity/100,'text-align':'center','color':' #000'});
}
function dg_tips(left,top){
var floatdiv="