ホームページ >ウェブフロントエンド >jsチュートリアル >JQuery_jqueryに基づくリストドラッグソートの実装コード

JQuery_jqueryに基づくリストドラッグソートの実装コード

WBOY
WBOYオリジナル
2016-05-16 17:20:541320ブラウズ

要件

ドラッグ並べ替えは、名前から想像できるように、データの行を押したまま、希望の並べ替え位置までドラッグし、新しい並べ替えキューを保存します。

想い

最初にリスト行のアンカー ポイントを作成し、mousedown イベントと Mouseup イベントをバインドし、マウスが挿入したい位置に移動したら、オブジェクト行をターゲット行に移動し、通過したすべての行を並べ替えます。

アイデアは非常にシンプルですが、注意すべき問題がまだいくつかあります

1. 移動した位置が、対象行に挿入される位置とみなします。
2. 上下から移動する場合は最初と最後と判断します。
3. 上への移動と下への移動の処理

解決策

イベントについて

JavaScript でのマウスのプレスとリリースのイベントは onmousedown と onmouseup であり、JQuery ではマウスダウンとマウスアップです。したがって、ここではマウスダウンとマウスアップが使用されます。

まず、マウスの移動距離を判断する必要があるため、インターフェースに何本の線があり、各線の高さを知る必要があります



コードをコピーしますコードは次のとおりです:
var tbodyHeight=setting.frame.outerHeight(); //setting.frame、親オブジェクト
var lineNum=$("." settings.dgLine) .length; //setting.dgLine、各行のクラス名
var lineHeight=Math.ceil(tbodyHeight/lineNum);

必要なのは lineNum (行数) を取得することだけでなく、行の高さを計算することに加えて、index() を使用してシーケンス インデックス値

を使用して行をターゲット位置に移動することです。

mousedown イベントがトリガーされると、マウスの移動距離の計算を開始する必要があります。これは、ラインを移動する場所を決定するために使用されます

コードをコピー コードは次のとおりです。
dgid=$(this).attr( settings.id ); //モバイル行の ID、setting.id は、各行の ID をマークするために使用される名前です
thisIndex=$("#" settings.linePre dgid).index(); /行のインデックス、.linePre を設定、各行 ID は off
thisLineTop=$("#" settings.linePre dgid).offset().top //この行の上部の値
topDistance =thisIndex*lineHeight; //この行の最初の行の上部からの距離
downDistance=(lineNum-thisIndex-1)*lineHeight; //この行と最後の行の下部の間の距離

dgid は主に各行の識別子を区別するために使用されます。このような ID がないと、どの行がどの行であるかを区別できません。 ID を保存する人を定義します。プログラムは attr を使用してこの値を取得し、各行が独自の一意の値を持つようにします。

thisLineTop は主にマウスの移動位置に基づいて高さを計算し、行の高さとインデックス値に基づいてどの行に移動したかを判断するために使用されます。もう 1 つの機能は、移動するアンカー ポイントが押されたかどうかを判断することです。値がある場合、それは Yes を意味し、値がない場合、それはアンカー ポイントが押されていないことを意味し、マウス アップは実行されません。あらゆる操作。なぜこれを行うのでしょうか?ページ上のどこでマウスをクリックしても、mouseup イベントがトリガーされ、判定がなければ実行され続けるため、問題が発生します。

topDistance と downDistance は、マウスがリスト外に移動したかどうかを判断するために使用されます。リストから削除されている場合、つまりマウスの移動距離が topDistance または downDistance よりも大きい場合、それを行う必要があると判断できます。最初または最後の行に移動します。

mousedown イベントは主に次のいくつかのことを行います。もちろん、効果を高めるために、いくつかのことを追加することもできます。

コードをコピー コードは次のとおりです:
$("#" settings.linePre dgid ).css ('background',setting.lineHighlight); //モバイル行をハイライトします
var left=e.pageX 20;
var top=e.pageY;
dg_tips(left,top); /プロンプトレイヤーを作成します
$('body').css('cursor','move') //ページのマウスジェスチャーを変更します
$("body").disableSelection(); /押下を無効にする マウスをマウスの後ろに移動したときにページ要素を選択します
setting.frame.mousemove(function(e){ //プロンプトレイヤーをマウスの動きに追従させます
$("#dgf")。 css({"left":e.pageX settings.tipsOffsetLeft 'px',"top":e.pageY 'px'});
});

これらの目的は、操作をより効率的にすることだけです。たとえば、行を強調表示することで、どの行を操作しているのかをユーザーに知らせることができます。プロンプト層も同様に機能します。

選択の無効化については、.disableSelection(); jQuery_UI を使用している場合は、これを直接使用できます。

コードをコピー コードは次のとおりです:

$('body').each(function() { -select':'none',
キットユーザー選択':'なし',
'ユーザー選択' :'none'
}).each(function() {
this.onselectstart = function() { return false; };
});
});


禁止された選択をキャンセル

$('body').each( function() { ',
'user-select':''
});
});



汎用性を考慮して、以下のコードでは .disableSelection();
は使用されません。
さて、これがマウスアップイベントです。ここでのmouseupイベントはbodyにバインドされています。mouseupがアンカーポイントのみにバインドされている場合、マウスがアンカーポイントの外に移動してマウスを放したときに、mouseupイベントが実行されないことがわかります。他のオブジェクトのマウスアップだと思います。したがって、最も安全な方法は $('body').mouseup を使用することです。基本的には問題ないでしょう。
mouseup がトリガーされた後、まず thisLineTop に無意味なイベントの実行を防ぐ値があるかどうかを判断する必要があります。次に、マウスの移動距離が正か負か、つまり上または下を決定します。

var moveDistance=e.pageY-thisLineTop;

異なる方向に応じて異なる処理を実行します

コードをコピー

コードは次のとおりです:if(moveDistance<0){ if( thisIndex!=0){ moveDistance=Math.abs(moveDistance); //負の数値の場合は絶対値を取る
if(moveDistance>lineHeight/2){ //移動距離が行の高さ 1/2 を超える
if(moveDistance>topDistance){ //移動距離が行から上端までの距離より大きい場合
focusIndex=0;
}else {
focusIndex=thisIndex-Math.ceil( moveDistance/lineHeight);
}
$("." settings.dgLine).eq(focusIndex).before($("#" settings.linePre dgid ));//ターゲット位置にラインを挿入
}
}
}else{
if(thisIndex!=lineNum-1){
if(moveDistance>lineHeight/2 lineHeight ){
if(moveDistance>down​​Distance){
focusIndex=lineNum-1;
}else{
focusIndex=thisIndex Math.ceil(moveDistance/lineHeight)-1;
}
$("." settings.dgLine).eq( focusIndex).after($("#" settings.linePre dgid));
}
}
}



移動距離が行高さの1/2を超えるかどうかを判定するのは、小さな点を移動するだけであれば、移動していないとみなすことができるためです。目標指標値の計算には Math.ceil を使用し、移動距離が 0 より大きい場合は下向きのためキャリーが -1 となります。

上に移動する場合と下に移動する場合では、前後で異なる挿入方法が使用されます。なぜ前と後が使用されるのかを考えてみてください。
移動後も、マウスを押したときに使用されたエフェクトを削除する必要があります

コードをコピー

コードは次のとおりです:$("#dgf").remove (); //プロンプトレイヤーを削除します$("#" settings.linePre dgid).css('background','');//強調表示された行を通常の行に変換しますdgid='';/ / モバイル回線の ID 値は空のままにしておきます
thisLineTop=0;//モバイル回線の Top 値を 0 に変更します
$('body').css('cursor','default'); // マウスジェスチャの変更はデフォルトです



基本的にはこのような状況ですが、主な問題は動きの処理と挿入する場所の決定です。他はすべて非常にシンプルです。

更新データ部分を含む完全なパッケージ プログラムを以下に示します

コードをコピー

コードは次のとおりです:

/*
*
*  DragList.js
*  @author fuweiyi

*/
(function($){
 $.fn.DragList=function(setting){
  var _setting = {
   frame : $(this),
   dgLine : 'DLL',
   dgButton : 'DLB',
   id : 'action-id',
   linePre : 'list_',
   lineHighlight : '#ffffcc',
   tipsOpacity : 80,
   tipsOffsetLeft : 20,
   tipsOffsetTop : 0,
   JSONUrl : '',
   JSONData : {},
   maskLoaddingIcon : '',
   maskBackgroundColor : '#999',
   maskOpacity : 30,
   maskColor : '#000',
   maskLoadIcon:'',
  };
  var setting = $.extend(_setting,setting);

  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 var end=thisIndex var ids='',vals='';
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=' settings.maskOpacity ')','moz-opacity':setting.maskOpacity/100,'opacity':setting.maskOpacity/100,'text-align':'center','color':' #000'});
}

function dg_tips(left,top){
var floatdiv="
移転一条记录
";
$('body').append(floatdiv);
}

function unselect(){
$('body').each(function() {
$(this).attr('unselectable', 'on').css({
'- moz-user-select':'none',
'-webkit-user-select':'none',
'user-select':'none'
}).each(function() {
this.onselectstart = function() { return false; };
});
});
}

function onselect(){
$('body').each(function() {
$( this).attr('選択不可', '').css({
'-moz-user-select':'',
'-webkit-user-select':'',
' user-select':''
});
});
}
}
})(jQuery);

使用

复制代 代码如下:









< !--{loop $lists $k $list}-->



< ;/tr>


拖動 名前
这里是一行