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 });

效果圖

如需轉載,請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM