对移动效果提取出了一个公共方法,用JS封装了一个类,可以直接NEW出来,就可以使用了
//进入拖动模式
$("#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样式进行调整。
.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插件支持
/*
为行添加移动动作
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