xfrontend/web/src/Tdrag.js
2021-08-12 17:17:05 +08:00

587 lines
23 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*! Tdrag 0.0.1 */
/**
* Created by Tezml on 2016/5/26
* You can modify my source code, if you have a good idea or a problem can be encountered by e-mail: tezml@tezml.com to find me.
* 如果你想在项目中使用该插件,请不要删除该注释。
*/
;(function($,window,document,undefined){
jQuery(function() {
//插件制作
$.fn.Tdrag = function (opt) {
var call = {
scope: null,//父级
grid: null,//网格
axis:"all",//上下或者左右
pos:false,//是否记住位置
handle:null,//手柄
moveClass:"tezml",//移动时不换位加的class
dragChange:false,//是否开启拖拽换位
changeMode:"point",//point & sort
cbStart:function(){},//移动前的回调函数
cbMove:function(){},//移动中的回调函数
cbEnd:function(){},//移动结束时候的回调函数
random:false,//是否自动随机排序
randomInput:null,//点击随机排序的按钮
animation_options:{//运动时的参数
duration:800,//每次运动的时间
easing:"ease-out"//移动时的特效ease-out、ease-in、linear
},
disable:false,//禁止拖拽
disableInput:null//禁止拖拽的按钮
};
var dragfn = new Dragfn(this, opt);
if (opt && $.isEmptyObject(opt) == false) {
dragfn.options = $.extend(call, opt);
} else {
dragfn.options = call;
}
dragfn.firstRandom=true;
var ele = dragfn.$element;
dragfn.pack(ele,false);
if(dragfn.options.randomInput!=null){
$(dragfn.options.randomInput).bind("click",function(){
dragfn.pack(ele,true);
})
}
//加载拓展jquery的函数
dragfn.loadJqueryfn()
};
//依赖构造函数
var Dragfn = function (ele, opt) {
this.$element = ele;
this.options = opt;
};
//构造函数方法
Dragfn.prototype = {
init: function (obj) {
var self = this;
self.ele=self.$element;
self.handle=$(obj);//手柄
self.options = self.options;
self.disable = self.options.disable;
self._start = false;
self._move = false;
self._end = false;
self.disX = 0;
self.disY = 0;
self.zIndex=1000;
self.moving=false;
self.moves="";
//父级
self.box = $.type(self.options.scope)==="string" ? self.options.scope : null;
//手柄
if(self.options.handle!=null){
self.handle=$(obj).find(self.options.handle);
}
//三个事件
self.handle.on("mousedown", function (ev) {
self.start(ev, obj);
obj.setCapture && obj.setCapture();
return false;
});
if(self.options.dragChange) {
$(obj).on("mousemove", function (ev) {
self.move(ev, obj);
});
$(obj).on("mouseup", function (ev) {
self.end(ev, obj);
});
}else{
$(document).on("mousemove", function (ev) {
self.move(ev, obj);
});
$(document).on("mouseup", function (ev) {
self.end(ev, obj);
});
}
},
//jquery调取函数时候用
loadJqueryfn: function(){
var self=this;
$.extend({
//返回按照index排序的回调函数
sortBox:function(obj){
var arr=[];
for (var s = 0; s < $(obj).length; s++) {
arr.push($(obj).eq(s));
}
for ( var i = 0; i < arr.length; i++) {
for ( var j = i + 1; j < arr.length; j++) {
if(Number(arr[i].attr("index")) > Number(arr[j].attr("index"))){
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr
},
//随机排序函数
randomfn:function(obj){
self.pack($(obj),true);
},
//开启拖拽
disable_open:function(){
self.disable=false;
},
//禁止拖拽
disable_cloose:function(){
self.disable=true;
}
});
},
toDisable: function(){
var self=this;
if(self.options.disableInput!=null){
$(self.options.disableInput).bind("click",function(){
if(self.disable==true){
self.disable=false
}else{
self.disable=true
}
})
}
},
start: function (ev, obj) {
var self = this;
self.moved=obj;
if (self.disable == true) {
return false
}
self._start = true;
var oEvent = ev || event;
self.disX = oEvent.clientX - obj.offsetLeft;
self.disY = oEvent.clientY - obj.offsetTop;
$(obj).css("zIndex",self.zIndex++);
self.options.cbStart();
},
move: function (ev, obj) {
var self = this;
if (self._start != true) {
return false
}
if(obj!=self.moved){
return false
}
self._move = true;
var oEvent = ev || event;
var l = oEvent.clientX - self.disX;
var t = oEvent.clientY - self.disY;
//有父级限制
if (self.box != null) {
var rule = self.collTestBox(obj,self.box);
if (l > rule.lmax) {
l = rule.lmax;
} else if (l < rule.lmin) {
l = rule.lmin;
}
if (t > rule.tmax) {
t = rule.tmax;
} else if (t < rule.tmin) {
t = rule.tmin;
}
}
if(self.options.axis=="all"){
obj.style.left = self.grid(obj, l, t).left + 'px';
obj.style.top = self.grid(obj, l, t).top + 'px';
}else if(self.options.axis=="y"){
obj.style.top = self.grid(obj, l, t).top + 'px';
}else if(self.options.axis=="x"){
obj.style.left = self.grid(obj, l, t).left + 'px';
}
/* if(self.options.changeWhen=="move") {
if (self.options.changeMode == "sort") {
self.sortDrag(obj);
} else if (self.options.changeMode == "point") {
self.pointmoveDrag(obj);
}
}else{
self.moveAddClass(obj);
}*/
if(self.options.pos==true){
self.moveAddClass(obj);
}
self.options.cbMove(obj,self);
},
end: function (ev, obj) {
var self = this;
if (self._start != true) {
return false
}
if(self.options.changeMode=="sort"&&self.options.pos==true){
self.sortDrag(obj);
}else if(self.options.changeMode=="point"&&self.options.pos==true){
self.pointDrag(obj);
}
if(self.options.pos==true){
self.animation(obj, self.aPos[$(obj).attr("index")]);
}
self.options.cbEnd();
if(self.options.handle!=null){
$(obj).find(self.options.handle).unbind("onmousemove");
$(obj).find(self.options.handle).unbind("onmouseup");
}else{
$(obj).unbind("onmousemove");
$(obj).unbind("onmouseup");
}
obj.releaseCapture && obj.releaseCapture();
self._start = false;
},
//算父级的宽高
collTestBox: function (obj, obj2) {
var self = this;
var l1 = 0;
var t1 = 0;
var l2 = $(obj2).innerWidth() - $(obj).outerWidth();
var t2 = $(obj2).innerHeight() - $(obj).outerHeight();
return {
lmin: l1,//取的l最小值
tmin: t1,//取的t最小值
lmax: l2,//取的l最大值
tmax: t2//取的t最大值
}
},
//算父级宽高时候干掉margin
grid: function (obj, l, t) {//cur:[width,height]
var self = this;
var json = {
left: l,
top: t
};
if ($.isArray(self.options.grid) && self.options.grid.length == 2) {
var gx = self.options.grid[0];
var gy = self.options.grid[1];
json.left = Math.floor((l + gx / 2) / gx) * gx;
json.top = Math.floor((t + gy / 2) / gy) * gy;
return json
} else if (self.options.grid == null) {
return json
} else {
console.log("grid参数传递格式错误");
return false
}
},
findNearest: function(obj){
var self=this;
var iMin=new Date().getTime();
var iMinIndex=-1;
var ele=self.ele;
for(var i=0;i<ele.length;i++){
if(obj==ele[i]){
continue;
}
if(self.collTest(obj,ele[i])){
var dis=self.getDis(obj,ele[i]);
if(dis<iMin){
iMin=dis;
iMinIndex=i;
}
}
}
if(iMinIndex==-1){
return null;
}else{
return ele[iMinIndex];
}
},
getDis: function(obj,obj2){
var self=this;
var l1=obj.offsetLeft+obj.offsetWidth/2;
var l2=obj2.offsetLeft+obj2.offsetWidth/2;
var t1=obj.offsetTop+obj.offsetHeight/2;
var t2=obj2.offsetTop+obj2.offsetHeight/2;
var a=l2-l1;
var b=t1-t2;
return Math.sqrt(a*a+b*b);
},
collTest: function(obj,obj2){
var self=this;
var l1=obj.offsetLeft;
var r1=obj.offsetLeft+obj.offsetWidth;
var t1=obj.offsetTop;
var b1=obj.offsetTop+obj.offsetHeight;
var l2=obj2.offsetLeft;
var r2=obj2.offsetLeft+obj2.offsetWidth;
var t2=obj2.offsetTop;
var b2=obj2.offsetTop+obj2.offsetHeight;
if(r1<l2 || r2<l1 || t2>b1 || b2<t1){
return false;
}else{
return true;
}
},
//初始布局转换
pack: function(ele,click){
var self=this;
self.toDisable();
if(self.options.pos==false){
for (var i = 0; i < ele.length; i++) {
$(ele[i]).css("position", "absolute");
$(ele[i]).css("margin", "0");
self.init(ele[i]);
}
}else if(self.options.pos==true) {
var arr = [];
if (self.options.random || click) {
while (arr.length < ele.length) {
var n = self.rnd(0, ele.length);
if (!self.finInArr(arr, n)) {//没找到
arr.push(n);
}
}
}
if (self.options.random == false || click != true) {
var n = 0;
while (arr.length < ele.length) {
arr.push(n);
n++
}
}
//如果是第二次以后随机列表,那就重新排序后再随机,因为我智商不够使,不会排了
if (self.firstRandom == false) {
var sortarr = [];
var n = 0;
while (sortarr.length < ele.length) {
sortarr.push(n);
n++
}
for (var i = 0; i < ele.length; i++) {
$(ele[i]).attr("index", sortarr[i]);
$(ele[i]).css("left", self.aPos[sortarr[i]].left);
$(ele[i]).css("top", self.aPos[sortarr[i]].top);
}
}
//布局转化
self.aPos = [];
if (self.firstRandom == false) {
//不是第一次
for (var j = 0; j < ele.length; j++) {
self.aPos[j] = {
left: ele[$(ele).eq(j).attr("index")].offsetLeft,
top: ele[$(ele).eq(j).attr("index")].offsetTop
};
}
} else {
//第一次
for (var j = 0; j < ele.length; j++) {
self.aPos[j] = {left: ele[j].offsetLeft, top: ele[j].offsetTop};
}
}
//第二个循环布局转化
for (var i = 0; i < ele.length; i++) {
$(ele[i]).attr("index", arr[i]);
$(ele[i]).css("left", self.aPos[arr[i]].left);
$(ele[i]).css("top", self.aPos[arr[i]].top);
$(ele[i]).css("position", "absolute");
$(ele[i]).css("margin", "0");
self.init(ele[i]);
}
self.firstRandom = false;
}
},
//移动时候加class
moveAddClass: function(obj){
var self=this;
var oNear=self.findNearest(obj);
$(self.$element).removeClass(self.options.moveClass);
if(oNear && $(oNear).hasClass(self.options.moveClass)==false){
$(oNear).addClass(self.options.moveClass);
}
},
//给li排序
sort: function(){
var self=this;
var arr_li=[];
for (var s = 0; s < self.$element.length; s++) {
arr_li.push(self.$element[s]);
}
for ( var i = 0; i < arr_li.length; i++) {
for ( var j = i + 1; j < arr_li.length; j++) {
if(Number($(arr_li[i]).attr("index")) > Number($(arr_li[j]).attr("index"))){
var temp = arr_li[i];
arr_li[i] = arr_li[j];
arr_li[j] = temp;
}
}
}
return arr_li;
},
//点对点的方式换位
pointDrag: function(obj){
var self=this;
//先拍序
var oNear=self.findNearest(obj);
if (oNear) {
self.animation(obj,self.aPos[$(oNear).attr("index")]);
self.animation(oNear, self.aPos[$(obj).attr("index")]);
var tmp;
tmp = $(obj).attr("index");
$(obj).attr("index", $(oNear).attr("index"));
$(oNear).attr("index", tmp);
$(oNear).removeClass(self.options.moveClass);
} else if (self.options.changeWhen == "end") {
self.animation(obj, self.aPos[$(obj).attr("index")]);
}
},
//排序的方式换位
sortDrag: function(obj){
var self=this;
//先拍序
var arr_li=self.sort();
//换位置
var oNear=self.findNearest(obj);
if(oNear){
if(Number($(oNear).attr("index"))>Number($(obj).attr("index"))){
//前换后
var obj_tmp=Number($(obj).attr("index"));
$(obj).attr("index",Number($(oNear).attr("index"))+1);
for (var i = obj_tmp; i < Number($(oNear).attr("index"))+1; i++) {
self.animation(arr_li[i],self.aPos[i-1]);
self.animation(obj,self.aPos[$(oNear).attr("index")]);
$(arr_li[i]).removeClass(self.options.moveClass);
$(arr_li[i]).attr("index",Number($(arr_li[i]).attr("index"))-1);
}
}else if(Number($(obj).attr("index"))>Number($(oNear).attr("index"))){
//后换前
var obj_tmp=Number($(obj).attr("index"));
$(obj).attr("index",$(oNear).attr("index"));
for (var i = Number($(oNear).attr("index")); i < obj_tmp; i++) {
self.animation(arr_li[i],self.aPos[i+1]);
self.animation(obj,self.aPos[Number($(obj).attr("index"))]);
$(arr_li[i]).removeClass(self.options.moveClass);
$(arr_li[i]).attr("index",Number($(arr_li[i]).attr("index"))+1);
}
}
}else{
self.animation(obj,self.aPos[$(obj).attr("index")]);
}
},
//运动函数(后期再加参数)
animation: function(obj,json){
var self=this;
//考虑默认值
var options=self.options.animation_options; /*|| {};
options.duration=self.options.animation_options.duration || 800;
options.easing=options.easing.duration.easing || 'ease-out';*/
var self=this;
var count=Math.round(options.duration/30);
var start={};
var dis={};
for(var name in json){
start[name]=parseFloat(self.getStyle(obj,name));
if(isNaN(start[name])){
switch(name){
case 'left':
start[name]=obj.offsetLeft;
break;
case 'top':
start[name]=obj.offsetTop;
break;
case 'width':
start[name]=obj.offsetWidth;
break;
case 'height':
start[name]=obj.offsetHeight;
break;
case 'marginLeft':
start[name]=obj.offsetLeft;
break;
case 'borderWidth':
start[name]=0;
break;
//...
}
}
dis[name]=json[name]-start[name];
}
var n=0;
clearInterval(obj.timer);
obj.timer=setInterval(function(){
n++;
for(var name in json){
switch(options.easing){
case 'linear':
var a=n/count;
var cur=start[name]+dis[name]*a;
break;
case 'ease-in':
var a=n/count;
var cur=start[name]+dis[name]*a*a*a;
break;
case 'ease-out':
var a=1-n/count;
var cur=start[name]+dis[name]*(1-a*a*a);
break;
}
if(name=='opacity'){
obj.style.opacity=cur;
obj.style.filter='alpha(opacity:'+cur*100+')';
}else{
obj.style[name]=cur+'px';
}
}
if(n==count){
clearInterval(obj.timer);
options.complete && options.complete();
}
},30);
},
getStyle: function(obj,name){
return (obj.currentStyle || getComputedStyle(obj,false))[name];
},
//随机数
rnd: function(n,m){
return parseInt(Math.random()*(m-n)+n);
},
//在数组中找
finInArr: function(arr,n){
for(var i = 0 ; i < arr.length; i++){
if(arr[i] == n){//存在
return true;
}
}
return false;
}
}
})
})(jQuery,window,document);