需求:
(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 *电邮:[email protected]
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);
时间: 2024-10-26 06:46:31