您的位置:首页 > Web前端 > JQuery

JavaScript、 jQuery行拖拽、排序

2015-09-11 14:39 736 查看
对移动效果提取出了一个公共方法,用JS封装了一个类,可以直接NEW出来,就可以使用了

[code]    //进入拖动模式
    $("#editButton").click(function(){
        var moveObj = $("tbody tr");       

        //移动时辅助提示信息,重写
        MoveTR.prototype.show_moveMsg = function(){
            show_moveMsg(this);//根据需求重写的方法
        };

        //移动结果控制  重写
        MoveTR.prototype.lesMove = function(){
            lesMove(this);  //根据需求重写的方法 
        };
        var move = new MoveTR(moveObj); //为行添加移动事件
    });


移动效果:

具体效果需要自己去重写,包括移动结果的控制和显示的提示信息



移动层的显示效果基本是复制的列表TR,具体可以参考下面的示例对css样式进行调整。

[code].moveFloor {
    width:98%;
    position:absolute;
    opacity:0.6;
    filter:alpha(opacity=40); /* For IE8 and earlier */
    border:1px dashed Orange;
    border-radius:5px;
    box-shadow:5px 5px 2px #bbbbbb;
}

.moveMsg{
    position:absolute;
    border: 1px dashed Orange;
    background-color:Orange;
    border-radius:5px;
    box-shadow:3px 3px 2px #999999;
}
.moveMsg font{
    font:12px/180% Arial, Helvetica, sans-serif,"宋体";
    padding:1em 1em;
}


【1】在封装的过程中遇到一个问题:

在用new MoveTR($(‘tr’));的时候,在构造函数中直接对所有tr注册事件,事件执行的方法中需要再次调用MoveTR的方法,但此时使用this调用会产生问题,因为此时的this已经指向了触发事件的TR(DOM对象),和注册事件外面的this指向的内容不同。所以此时要将外面的this重新起个名字 比如:var thisObj = this;这样就可以在MoveTR成员内声明的方法中调用MoveTR中的任意对象了,JS方法也是一种对象(Function对象)。想详细了解,可以参考文章后面的链接。

【2】在拖动过程中要禁用鼠标的选择文本功能:

如果不禁用,会产生拖拽过程中把列表内容选中的尴尬。

unselect() 禁用, onselect() 启用



MoveTR.js 可以作为公共方法使用,需要jQuery插件支持

[code]/* 
    为行添加移动动作
    moveObjs 为jQuery对象,tr数组
    复用根据需要重写  show_moveMsg()  lesMove()  方法

*/  
function MoveTR(moveObjs){
    this.moveObjs = moveObjs;
    this.beginMoving = false;
    this.count = moveObjs.length;
    this.startObj = new Object();
    this.startIndex = 0;
    this.endIndex = 0;
    this.endObj = new Object();
    this.moveFloor_top =  0;
    this.trHeight = 0;
    this.addTop = 0;
    this.mouseShowHeight = 0 ;  //鼠标距离顶端距离
    this.init(); //【1】
}
MoveTR.prototype.init = function(){
    var movetrObj = this;  
    //【1】
    //注意这里,此this指向MoveTR的实例,
    //而注册事件function中的this指向触发事件的元素(DOM对象)
    //所以此处this要重新命名,以防止后面无法调用MoveTR中的方法或元素
    if(movetrObj.moveObjs.length > 0){
        movetrObj.moveObjs.mousedown(function(obj){
            movetrObj.MouseDown(this,obj);
        });
        movetrObj.moveObjs.mouseup(function(obj){
            //MouseUpToMove(this,obj);
            movetrObj.MouseUp(obj);
        });
        movetrObj.moveObjs.mousemove(function(obj){
            //MouseMoveToMove(this,obj);
            movetrObj.MouseMove(obj);
        }); 
    }
}

MoveTR.prototype.clear = function(){
    if(this.count < 1){
        return "Error: count=0";
    }
    this.onselect();
    moveObjs.removeClass("moveElement");
}

MoveTR.prototype.MouseDown = function(obj, mouse){
         //鼠标点下事件
         //showWinMsg("这样可以的","OK",0.1);
         this.startObj = obj;
         this.startIndex =$(obj ).parent().children().index(this.startObj);  //开始的tr index
         this.trHeight = $(this.startObj).css("height").replace("px","");
         this.startObj.style.zIndex = 1;
         this.minTop = $(this.startObj).parents('tbody').offset().top;
         this.maxTop = $(this.startObj).parent().children().eq(this.count - 1 ).offset().top -( - this.trHeight);
         //startObj.mouseDownY=mouse.clientY;
         //startObj.mouseDownX=mouse.clientX;
         this.beginMoving = true;
         this.startObj.setCapture();
         this.show_moveDiv();
}

MoveTR.prototype.MouseMove = function (mouse){
        //鼠标移动事件
        if(! this.beginMoving) {
             return false;
        }
        this.endIndex = Math.floor( this.addTop / this.trHeight ) + this.startIndex;   //获得结束位置的 index, Math.floor向下取整,ceil向上取整
        this.endObj = $(this.startObj).parent().children().get( this.endIndex );
        this.mouseShowHeight = mouse.clientY;    //鼠标距离document上部基准线高度
        //$(this.startObj).addClass("clickTR");
        this.move_moveDiv();  //移动效果层
        this.show_moveMsg();  //显示提示信息

}

MoveTR.prototype.MouseUp = function ( mouse){
     $(".moveFloor").remove();//删除效果层
     $(".moveMsg").remove();//删除提示信息层
     //鼠标弹起事件
    // showWinMsg(this.beginMoving,"OK",0.5);
     if(! this.beginMoving) {
         return false;
     }
    this.beginMoving = false;

    //鼠标相对开始单元格移动距离,单位px, + 滚动条卷上去的高度以修正误差
    this.addTop = mouse.clientY - $(this.startObj).offset().top + $(document).scrollTop();  
    this.endIndex = Math.floor( this.addTop / this.trHeight ) + this.startIndex;   //获得结束位置的 index, Math.floor向下取整,ceil向上取整
    this.endObj = $(this.startObj).parent().children().get( this.endIndex );
    this.lesMove();
}

//创建一个跟随鼠标的移动层
MoveTR.prototype.show_moveDiv = function (){

        var floatdiv = $( this.startObj).eq(0).clone();//复制一个当前移动的对象
        floatdiv.addClass("moveFloor");  //移动层
        this.moveFloor_top = $(this.startObj).offset().top -5;
        var left = $(this.startObj).offset().left -3;
        floatdiv.css({'top':this.moveFloor_top +'px','left:':left +'px'});  //指定初始位置

        var children = floatdiv.children();
        if(children.length > 0){
            var ths = $(this.startObj).parents("table").find("thead tr").eq(0).children();  //获得标题元素
            //alert(ths.length);
            var ths_index = 0;
            //获取显示的内容
            //showWinMsg(tds.length,"OK",1);
            for(var i =0 ;i< children.length;i++)
            {  
                var width = $(ths[ths_index]).css("width");
                if(width != "" && width !="undefined"){
                    $(children[i]).css({"width": width  }) ;
                    if(ths_index < ths.length-1){
                        ths_index ++ ;
                    }
                }else{
                    $(children[i]).css({"width": "50px" }) ;
                }
            }
        }
        $(this.startObj).parents('tbody').append(floatdiv);
        $(this.startObj).parents('tbody').append("<div id='moveMsg' class='moveMsg' hidden></div>");
    }
//移动  效果层
MoveTR.prototype.move_moveDiv = function  (){
    var hiddenHeight = $(document).scrollTop(); //滚动条上部隐藏高度
    var documentHeight = $(document).height();  //显示区域总高度,隐藏+显示
    var showHeight =  $(window).height();       //当前框架的高度

    var floatdiv =$(".moveFloor");
    this.addTop =  this.mouseShowHeight - $(this.startObj).offset().top + hiddenHeight;

    this.moveFloor_top = $(this.startObj).offset().top - 5 + this.addTop;

    //var trHeight = $(this.startObj).css("height").replace("px","");

    //showWinMsg(showHeight+"|"+maxTop+"|"+mouseShowHeight+"|"+top,"OK",1);
    if( this.mouseShowHeight > 0 && this.mouseShowHeight < hiddenHeight){
        $(document).scrollTop(hiddenHeight - this.trHeight );  //鼠标在显示区域上部,向上滚动
    }
    if( this.mouseShowHeight > showHeight - 2 * this.trHeight ){
        $(document).scrollTop(hiddenHeight -( - this.trHeight ));   //鼠标持续向下移动,向下滚动
    }

    //var startIndex =$("#tableList tbody tr").index(this.startObj);
    //var endIndex = Math.floor( this.addTop/this.trHeight ) + this.startIndex;
    if( this.moveFloor_top < this.minTop ){
        this.moveFloor_top = this.minTop  - this.trHeight ;
    }
    if(this.moveFloor_top > this.maxTop){ 
        this.moveFloor_top = this.maxTop + Math.ceil(this.trHeight /3) ;
    }

    floatdiv.css({'top':this.moveFloor_top+'px'}); 

    this.presentObj = $(this.startObj).parent().children().get(this.endIndex );
}

MoveTR.prototype.lesMove = function(){
    if(this.startIndex == this.endIndex){
        return; 
    }else if(this.endIndex >= 0 && this.endIndex < this.count){
        //拖动后,如果目的位置与原位置的首页显示属性不一致,则修改为目的位置的值

        if(this.startIndex < this.endIndex){
            //往下拖动
            $(this.startObj).insertAfter(this.endObj);
        }else{
            //往上拖动
            $(this.startObj).insertBefore(this.endObj);
        }
    }
}

MoveTR.prototype.show_moveMsg  = function (){
    //辅助性提示信息
    //moveFlag  ()
    var showStr = "移动到";
    var moveMsg_left = this.trHeight - (-5);
    var moveMsg_top = this.moveFloor_top -(-this.trHeight-5) ;
    $(".moveMsg").css({'top':moveMsg_top+'px','left': moveMsg_left+'px'});
    $(".moveMsg").hide();
    if(showStr != ""){
        $(".moveMsg").html("<font>"+showStr+"</font>");
        $(".moveMsg").show();
    }
}
//禁用鼠标选择文字
MoveTR.prototype.unselect = function(){
    $('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; };
        });
    });
}
//启用鼠标选择文字
MoveTR.prototype.onselect = function(){
    $('body').each(function() {           
        $(this).attr('unselectable', '').css({
         '-moz-user-select':'',
         '-webkit-user-select':'',
         'user-select':''
        });
    });
}
//帮助
MoveTR.prototype.help = function(){
    return 
    "为行添加移动动作:<br>" 
    +"使用方法   var movetr = new MoveTR($('tbody tr') );  参数为jQuery对象(tr数组)<br>"
    +"  //移动时辅助提示信息,重写<br>" 
    +"  MoveTR.prototype.show_moveMsg = function(){<br>"    
    +"      show_moveMsg(this);<br>"    
    +"  };<br>" 
    +"  //移动结果控制  重写<br>"   
    +"  MoveTR.prototype.lesMove = function(){<br>" 
    +"      lesMove(this);<br>" 
    +"  };<br>"
    +"复用根据需要重写  show_moveMsg()  lesMove()  方法<br>";
}


参考资料:

认识JS中的FUNCTION和THIS:

http://www.cnblogs.com/yuzhongwusan/archive/2012/04/09/2438569.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: