• wex5——实现拖拽替换效果


    继之前发表的文章——元素拖拽之后,终于完成了最终效果,拖拽替换,并且对之前的代码进行了优化。也算有始有终了。
    之前只是将代码大概贴了出来,没有进行详细讲解。这次也会弥补上一次的不足之处,将代码产生的一个大概过程阐述一下。一来提升自己,而来希望也能帮助到别人。

    插句题外话,自入行以来,真心觉得程序猿大多都特别慷慨,从来不吝啬自己所知道的技术。多少有些感动,没有那么多人不吝啬的指点,我也不会成长成现在这样

    回归正题。

    第一步是搭建数据库,先在前台界面把内容展示出来

    这里不做过多赘述,如果对于数据库与前台界面展示数据不清楚的,可以先看之前的文章wex5 ——— 前台界面展示数据库内容

    搭建一个名为drag的数据库,在数据库中件名为items的表,字段如下。

    新建drag服务,并在前台界面调用。在界面添加baasData数据库,绑定drag服务。

    并用list数据组件对数据进行展示

    图为对数据进行初次展示的效果。

    下面主要讲解实现效果的代码:

    js实现的大概思路还是主要包括三部分:开始——移动——结束

    手指触屏对应touchstart

    手指移动对应touchmove

    手指松开对应touchend

    当然在这之前还得做一下准备工作——定义一些全局参数用于承载被拖动的元素,被替换的元素和一些坐标点等

    var Model = function(){
            this.callParent();
            
            this.curTarget = null;//被拖动的元素
            this.curPos = null;//坐标点
            this.dropTarget = null;//被替换的元素
            this.iMouseDown = null;//手指是否触屏
            this.lMouseState = null;//状态
            this.dragreplaceCont = [];//将遍历的元素放于此数组中
            this.mouseOffset = null;//鼠标得偏移
            this.callbackFunc = null;//回调函数
        };

    在modelLoad中,新建一个div用于承载被拖动的元素

    并且遍历要拖动的元素,将他们放置在数组中,用于之后的匹配元素做准备,且设置他们为可拖动状态

    Model.prototype.modelLoad = function(event){
            //辅助层用来显示拖拽 
            dragHelper = document.createElement('DIV'); 
            dragHelper.setAttribute("class",'dragHelper czYfqmm ')
            dragHelper.style.cssText = 'position:absolute;display:none;'; 
            document.body.appendChild(dragHelper); 
            
            var dragitems = document.getElementById('displayRoom').getElementsByTagName("a");//获取可拖动的所有元素
            for(var i=0;i<dragitems.length;i++){//遍历可拖动的元素
                this.dragreplaceCont.push(dragitems[i]); 
                dragitems[i].setAttribute('candrag', '1'); 
            }
        };

    给元素绑定以上三个事件


    首先当然是在start中记录状态值

    Model.prototype.start = function(event){
            //记录变量状态 
            this.iMouseDown = true; 
        };

    接下来就是移动的动作

    1、先获取当前鼠标点击的元素

    2、判断当前是否为可拖动状态

    3、将当前元素赋值给之前定义的全局参数this.curTarget

    4、获取元素的坐标点,以及按下的坐标点对于元素左上角的偏移量

    5、清空之前在modelload中定义的辅助层dragHelper,将当前元素this.curTarget放进去,设置dragHelper为可见状态,当前元素this.curTarget不可见,

    6、记录起始坐标点并且,如果处于移动状态,则设置辅助层dragHelper的top和left值,使其实时移动(使用css的position达到移动效果)

    7、遍历各个元素,看当前在移动的元素是否与其中某个除自己之外的元素重合,

    8、如果重合,则将被重合的元素赋值给全局变量this.dropTarget,并给this.dropTarget添加被选中的样式

    最后是鼠标松开的动作:

    1、判断是否有被选中的元素和要被替换的元素

    2、获取两个元素所在的行数据,并分别设置两个行数据的值,即对两个值进行替换

    3、判断两个行数据是否被改变过,如果有则保存数据,并对一些全局参数进行还原,以备下一次的拖动替换

    不知道怎么上传压缩包,所以就用笨方法上传代码了。

     下面附上完整的代码

      1 define(function(require){
      2     var $ = require("jquery");
      3     var justep = require("$UI/system/lib/justep");
      4     
      5     var Model = function(){
      6         this.callParent();
      7         
      8         this.curTarget = null;
      9         this.curPos = null;
     10         this.dropTarget = null;
     11         this.iMouseDown = null;
     12         this.lMouseState = null;
     13         this.dragreplaceCont = [];
     14         this.mouseOffset = null;
     15         this.callbackFunc = null;
     16     };
     17 
     18     Model.prototype.modelLoad = function(event){
     19         //辅助层用来显示拖拽 
     20         dragHelper = document.createElement('DIV'); 
     21         dragHelper.setAttribute("class",'dragHelper czYfqmm ')
     22         dragHelper.style.cssText = 'position:absolute;display:none;'; 
     23         document.body.appendChild(dragHelper); 
     24         
     25         var dragitems = document.getElementById('displayRoom').getElementsByTagName("a");//获取可拖动的所有元素
     26         for(var i=0;i<dragitems.length;i++){//遍历可拖动的元素
     27             this.dragreplaceCont.push(dragitems[i]); 
     28             dragitems[i].setAttribute('candrag', '1'); 
     29         }
     30     };
     31     
     32     Model.prototype.start = function(event){
     33         //记录变量状态 
     34         this.iMouseDown = true; 
     35     };
     36 
     37     Model.prototype.move = function(event){
     38         ev = event || window.event; 
     39         var target = ev.target || ev.srcElement; 
     40         var mousePos = this.mouseCoords(ev);
     41         //如果当前元素可拖拽 
     42         var dragObj = target.getAttribute('candrag'); 
     43         if (dragObj != null) {    
     44             if (this.iMouseDown && !this.lMouseState) {
     45                 //刚开始拖拽 
     46                 this.curTarget = target; 
     47                 this.curPos = this.getPosition(target); 
     48                 this.mouseOffset = this.getMouseOffset(target, ev); 
     49                 // 清空辅助层 
     50                 for (var i = 0; i < dragHelper.childNodes.length; i++) dragHelper.removeChild(dragHelper.childNodes[i]); 
     51                 //克隆元素到辅助层,并移动到鼠标位置 
     52                 dragHelper.appendChild(this.curTarget.cloneNode(true)); 
     53                 dragHelper.style.display = 'block'; 
     54                 dragHelper.firstChild.removeAttribute('data-bind');
     55                 dragHelper.firstChild.removeAttribute('candrag'); 
     56                 dragHelper.firstChild.setAttribute("class","czYfqmm");
     57                 //记录拖拽元素的位置信息 
     58                 this.curTarget.setAttribute('startWidth', parseInt(this.curTarget.offsetWidth)); 
     59                 this.curTarget.setAttribute('startHeight', parseInt(this.curTarget.offsetHeight)); 
     60                 this.curTarget.style.background = 'none'; 
     61                 //记录每个可接纳元素的位置信息,这里一次记录以后多次调用,获取更高性能 
     62                 for (var i = 0; i < this.dragreplaceCont.length; i++) { 
     63                     with (this.dragreplaceCont[i]) { 
     64                         if (this.dragreplaceCont[i] == this.curTarget) 
     65                         continue; 
     66                         var pos = this.getPosition(this.dragreplaceCont[i]); 
     67                         setAttribute('startWidth', parseInt(offsetWidth)); 
     68                         setAttribute('startHeight', parseInt(offsetHeight)); 
     69                         setAttribute('startLeft', pos.x); 
     70                         setAttribute('startTop', pos.y); 
     71                     } 
     72                 } 
     73             }
     74         }
     75         //正在拖拽 
     76         if (this.curTarget != null) {
     77             // move our helper div to wherever the mouse is (adjusted by mouseOffset) 
     78             dragHelper.style.top = mousePos.y -this.mouseOffset.y + "px"; 
     79             dragHelper.style.left = mousePos.x -this.mouseOffset.x + "px";
     80             //拖拽元素的中点 
     81             var xPos = mousePos.x; 
     82             var yPos = mousePos.y; 
     83             var havedrop = false; 
     84             for (var i = 0; i < this.dragreplaceCont.length; i++) { 
     85                 with (this.dragreplaceCont[i]) { 
     86                     if (this.dragreplaceCont[i] == this.curTarget) 
     87                     continue;
     88                     if ((parseInt(getAttribute('startLeft')) < xPos) && (parseInt(getAttribute('startTop')) < yPos) && ((parseInt(getAttribute('startLeft')) + parseInt(getAttribute('startWidth'))) > xPos) && ((parseInt(getAttribute('startTop')) + parseInt(getAttribute('startHeight'))) > yPos)) { 
     89                         
     90                         this.dropTarget = this.dragreplaceCont[i];  93                         havedrop = true; 
     94                         this.dropTarget.className = 'czYfqmm usr catch'; 
     97                         break; 
     98                     } 
     99                 } 
    100             } 
    101             if (!havedrop && this.dropTarget != null) { 
    102                 this.dropTarget.className = 'czYfqmm usr'; 
    103                 this.dropTarget = null; 
    104             } 
    105         }//正在拖拽end 
    106         this.lMouseState = this.iMouseDown;
    107         if (this.curTarget) return false; //阻止其它响应(如:鼠标框选文本) 
    108     };
    109 
    110     Model.prototype.end = function(event){
    111         if (this.curTarget) { 
    112             dragHelper.style.display = 'none'; //隐藏辅助层 
    113             if (this.dropTarget != null) { 
    114                     //有元素接纳,两者互换 
    115                     var datass = this.comp("itemsData");
    116                     var rows = datass.find(['name'], [this.curTarget.innerHTML])[0];
    117                     var rows1 = datass.find(['name'], [this.dropTarget.innerHTML])[0];
    118                     var rowsname = this.curTarget.innerHTML;
    119                     var rows1name = this.dropTarget.innerHTML;
    120                     rows.val("name",rows1name);
    121                     rows1.val("name",rowsname);
    122                     this.dropTarget.className = 'czYfqmm usr'; 
    123                     this.dropTarget = null; 
    124                     if (this.callbackFunc != null) { 
    125                         this.callbackFunc(this.curTarget); 
    126                     } 
    127                     //如果两者已替换,则保存数据库
    128                     if(rows.row.name.changed && rows1.row.name.changed){
    129                         datass.saveData({
    130                             "onSuccess" : function(event){
    131                                 console.log("替换成功");
    132                             }
    133                         })
    134                     }
    135             }
    136             this.curTarget.style.background = 'green';
    137             this.curTarget.style.visibility = 'visible'; 
    138             this.curTarget.setAttribute('candrag', '1');
    139         }
    140         this.curTarget = null; 
    141         this.iMouseDown = false; 
    142         this.lMouseState = false; 
    143     };
    144     
    145     Model.prototype.mouseCoords = function(ev){//返回鼠标相对页面左上角的坐标
    146         if (ev.pageX || ev.pageY) { 
    147             return { x: ev.pageX, y: ev.pageY }; 
    148         } 
    149         return { 
    150             x:ev.originalEvent.touches[0].pageX,
    151             y:ev.originalEvent.touches[0].pageY    
    152         }; 
    153     }
    154     Model.prototype.getPosition = function(e){//返回当前item相对页面左上角的坐标
    155         var left = 0; 
    156         var top = 0; 
    157         while (e.offsetParent) { 
    158             left += e.offsetLeft + (e.currentStyle ? (parseInt(e.currentStyle.borderLeftWidth)).NaN0() : 0); 
    159             top += e.offsetTop + (e.currentStyle ? (parseInt(e.currentStyle.borderTopWidth)).NaN0() : 0); 
    160             e = e.offsetParent; 
    161         } 
    162         return { x: left, y: top }; 
    163     }
    164     Model.prototype.getMouseOffset = function(target, ev){//鼠标位置相对于item的偏移量
    165         ev = ev || window.event; 
    166         var docPos = this.getPosition(target); 
    167         var mousePos = this.mouseCoords(ev); 
    168         return { x: mousePos.x - docPos.x, y: mousePos.y - docPos.y }; 
    169     }
    170 
    171 
    172     return Model;
    173 });

    效果图

    如需转载,请注明出处。

  • 相关阅读:
    VS code 快捷键注释不能用[!----]解决办法
    vue 文件导出demo
    vue中后台返回的是数字,前端利用字典将其转换为相对应的中文
    java.lang.UnsupportedOperationException解决方法【转】
    Java List的remove()方法陷阱
    密码至少包含数字、大小写字母、特殊字符两种以上,长度不小于8位
    获取规格内数字
    获取时间段数据
    Echarts GL初次体验
    bootstrap-datetimepicker 如何获取值(日期)
  • 原文地址:https://www.cnblogs.com/ywang/p/6110598.html
Copyright © 2020-2023  润新知