我的開源框架之可拖拽功能實現


需求:

  (1)實現元素可拖拽

  (2)自定義拖拽范圍

  (3)自定義按下觸發拖拽的元素

  (4)支持拖拽過程中的事件監聽

實現思路:

  元素可拖拽的實現關鍵為,mousedown、mousemove、mouseup三大事件。mousedown為按下觸發拖動的事件,可以定義到元素本身或其他元素;mousemove為拖動范圍元素的事件,該事件負責重新設置拖動元素的位置屬性;mouseup為拖動范圍元素的事件,該事件主要為了釋放mousemove、mouseup事件。

  為避免當拖動元素內容有較大內容時,重新繪制位置造成的性能影響,可以采用拖動空元素(代理)來實現拖動過程,當拖動結束時,再調整實際元素的位置即可。

圖例:

客戶代碼:

 1 <body>
 2     <div id="header" style="padding-left:100px;padding-top:10px">
 3         <h1>可拖拽說明:</h1>       
 4         <p>(1)讓一個元素可以拖動,可以自定義拖拽范圍(第一個被設定了position的父元素),默認是window,可以自定義拖拽時鼠標的按下區域,默認是可拖拽元素本身</p>
 5         <p>(2)事件支持:鼠標按下准備拖拽;拖拽中;拖拽完成后</p>
 6         <p>(3)如果拖拽范圍是window,拖拽元素html會被放置在body下面</p>
 7         <p>(4)為獲得良好的拖動性能,請盡量采用代理拖動模式</p>
 8         <br />
 9         <br />
10     </div>
11     <div id="dragContainer" style="padding:10px; margin:0 auto;width:960px;height:350px;padding-top:20px; background:#cccccc;padding-left:100px">
12         <div id="dragDiv" style="width:400px;height:200px; background:#0094ff;">
13             <h2 id="title" style="background:#E8D379;height:35px;">標題..............</h2>
14             用戶名:<input type="text" value="hjwen" />
15             <p>(1)簡單實用的ui,不常用,不必要的功能,不實現</p>
16             <p>(2)只支持js創建,不支持html屬性形式,盡量保持html的整潔</p>        
17         </div>
18     </div> 
19     <script type="text/javascript"> 
20         var drag;
21         $(function () {
22             //drag = $("#dragDiv").draggable({ dragArea: 'dragContainer', mousedownObj: 'title' });//限定范圍,按標題拖動
23              drag = $("#dragDiv").draggable({  mousedownObj: 'title' });//window拖動范圍,按標題拖動
24             //drag = $("#dragDiv").draggable({ dragArea: 'dragContainer', mousedownObj: 'title',proxy:false });//非代理模式拖動
25             //默認,拖動范圍body,按元素拖動
26             //drag = $("#dragDiv").draggable({
27             //    onStart: function (params) {
28             //        //console.log("onStart"+JSON.stringify(params));
29             //    },
30             //    onDraging: function (params) {
31             //        //console.log("onDraging" + JSON.stringify(params));
32             //    },
33             //    onStop: function (params) {
34             //        //console.log("onStop" + JSON.stringify(params));
35             //    }
36             //});
37         });    
38     </script>
39 </body>

 

組件代碼:

  1 /******************************************
  2 *作者:hjwen
  3 *電郵:hjwen88@126.com
  4 *版本:1.0
  5 *版權許可:中國通用開源許可協議V1.0
  6 *說明:可拖動組件定義 
  7 ******************************************/
  8 (function ($) {
  9     /******渲染目標*******/
 10     /********拖拽: mousedown -- > mousemove --->mouseup ************/
 11     function renderHtml(target) {
 12         var settings = target.data('settings');
 13         target.css("position", "absolute");
 14         settings.dragArea.css("position", "relative");
 15         var offset;
 16         if (settings.isWindows) {//如果拖動范圍是window,則需要將對象放置在body下
 17             offset = target.offset();
 18             target.css({ top: offset.top, left: offset.left });
 19             target.appendTo(settings.dragArea);            
 20         }        
 21         var areawith = settings.dragArea.innerWidth();
 22         var areaheight = settings.dragArea.innerHeight();
 23         var targetwidth = target.innerWidth();
 24         var targeheight = target.innerHeight();
 25         var proxy = null;
 26         /*****************低版本ie鼠標捕獲特性處理**********************/
 27         var isCapture=false;
 28         if (typeof settings.mousedownObj[0].setCapture != 'undefined') {
 29             isCapture = true;
 30         }
 31         settings.mousedownObj.css("cursor", "move");
 32         settings.mousedownObj.bind("mousedown", function (e) {
 33             if (isCapture) {
 34                 settings.mousedownObj[0].setCapture();
 35             }
 36             //計算拖動范圍
 37             var offset = target.position();        
 38             var finalleft =target.css('left');
 39             var finaltop = target.css('top');            
 40             if (settings.proxy) {//創建空代理                
 41                 proxy = $("<div style=\"cursor:move;position: absolute; background:#C9C4F5; height: " + targeheight + "px; width:" + targetwidth + "px; opacity: 0.85;top:" + finaltop + ";left:" + finalleft + ";filter:alpha(opacity=85) \"></div>").insertAfter(target);
 42             }
 43             e.preventDefault();
 44             var diffX = e.clientX - offset.left;
 45             var diffY = e.clientY - offset.top;
 46             if (typeof settings.onStart === 'function') {
 47                 settings.onStart({ top: offset.top, left: offset.left });
 48             }
 49             settings.dragArea.bind("mousemove", function (e) { 
 50                 var left = e.clientX - diffX;
 51                 var top = e.clientY - diffY;
 52                 if (left < 0) {
 53                     left = 0;
 54                 } else {
 55                     var w =areawith - targetwidth;
 56                     if (left > w)
 57                         left = w;
 58                 }
 59                 if (top < 0) {
 60                     top = 0;
 61                 } else {
 62                     var h = areaheight - targeheight;
 63                     if (top > h)
 64                         top = h;
 65                 }
 66                 if (settings.proxy) {
 67                     finalleft = left;
 68                     finaltop = top;
 69                     proxy.css({ left: left + "px", top: top + "px" });
 70                 } else {                    
 71                     target.css({ left: left + "px", top: top + "px" });
 72                 }
 73                 if (typeof settings.onDraging === 'function') {
 74                     settings.onDraging({ top: top, left: left });
 75                 }
 76             });
 77             settings.dragArea.bind("mouseup", function (e) {
 78                 settings.dragArea.unbind("mousemove");
 79                 settings.dragArea.unbind("mouseup");               
 80                 if (settings.proxy) {
 81                     proxy.remove();
 82                     proxy = null;
 83                     target.css({ left: finalleft + "px", top: finaltop + "px" });
 84                 }
 85                 if (isCapture) {
 86                     settings.mousedownObj[0].releaseCapture();
 87                 }
 88                 if (typeof settings.onStop === 'function') {
 89                     settings.onStop({ top: finaltop, left: finalleft });
 90                 }
 91             });
 92         });
 93     };
 94     /************私有方法********************/
 95     /**********私有方法結束*******************/
 96     var methods = {        
 97         init: function (options) {
 98             if (typeof options == 'undefined')
 99                 options = {};
100             return this.each(function () {
101                 var $this = $(this);                
102                 if (typeof options.dragArea != 'undefined') {
103                     options.isWindows = false;
104                     if (typeof options.dragArea == 'string') {
105                         options.dragArea = $("#" + options.dragArea);
106                     }
107                 } else {
108                     options.isWindows = true;
109                 }               
110                 if (typeof options.mousedownObj == 'string') {
111                     options.mousedownObj = $("#" + options.mousedownObj);
112                 }
113                 $.fn.draggable.defaults.mousedownObj = $this;
114                 $.fn.draggable.defaults.dragArea = $(window.top.document.body);
115                 var settings = $this.data('settings');
116                 if (typeof settings == 'undefined') {
117                     settings = $.extend({}, $.fn.draggable.defaults, options);
118                     $this.data('settings', settings);
119                 } else {
120                     settings = $.extend({}, settings, options);
121                 }
122                 //創建ui布局
123                 renderHtml($this);
124                 if ($.myui.isDebug) {
125                     $.myui.log("jQuery.draggable init finish......");
126                 }
127             });
128         },
129         destroy: function (options) {
130             return $(this).each(function () {
131                 var $this = $(this);
132                 $this.removeData('settings');
133             });
134         }
135     };
136     /*****
137     *options= { mousedownObj: null,//鼠標按下對象/id,默認是拖動對象本身
138         proxy:true,//創建一個代理拖動對象,性能較好
139         dragArea: null, //默認拖動范圍對象/Id,不設置則為最頂層window(考慮到有iframe的情況)
140         onStart:function(params){},//開始拖動 params={top:x,left:y}
141         onDraging: function (params) { },//拖動中params={top:x,left:y}
142         onStop: function (params) { }//結束拖動params={top:x,left:y}
143         }
144     *****/
145     $.fn.draggable = function (dragArea) {
146         var method = arguments[0];
147         if (methods[method]) {
148             method = methods[method];
149             arguments = Array.prototype.slice.call(arguments, 1);
150         } else if (typeof (method) == 'object' || !method) {
151             if ($.myui.isDebug) {
152                 $.myui.log("jQuery.draggable init.....");
153             }
154             method = methods.init;
155         } else {
156             $.error('Method ' + method + ' does not exist on jQuery.draggable');
157             return this;
158         }
159         return method.apply(this, arguments);
160     };
161     //默認值
162     $.fn.draggable.defaults = {
163         mousedownObj: null,//鼠標按下對象/id,默認是拖動對象本身
164         proxy:true,//創建一個代理拖動對象,性能較好
165         dragArea: null, //默認拖動范圍對象/Id,不設置則為最頂層window(考慮到有iframe的情況)
166         onStart:null,//開始拖動
167         onDraging:null,//拖動中
168         onStop: null//結束拖動
169     };
170 })(jQuery);

 

 


免責聲明!

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



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