Moveable.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. define("dojox/mdnd/Moveable", [
  2. "dojo/_base/kernel",
  3. "dojo/_base/array",
  4. "dojo/_base/connect",
  5. "dojo/_base/declare",
  6. "dojo/_base/event",
  7. "dojo/_base/html",
  8. "dojo/_base/sniff",
  9. "dojo/_base/window"
  10. ],function(dojo){
  11. return dojo.declare(
  12. "dojox.mdnd.Moveable",
  13. null,
  14. {
  15. // summary:
  16. // Allow end-users to track a DOM node into the web page
  17. // handle: DOMNode
  18. // The node on which the user clicks to drag the main node.
  19. handle: null,
  20. // skip: Boolean
  21. // A flag to control a drag action if a form element has been focused.
  22. // If true, the drag action is not executed.
  23. skip: true,
  24. // dragDistance: Integer
  25. // The user clicks on the handle, but the drag action will really begin
  26. // if he tracks the main node to more than 3 pixels.
  27. dragDistance: 3,
  28. constructor: function(/*Object*/params, /*DOMNode*/node){
  29. // summary:
  30. // Configure parameters and listen to mousedown events from handle
  31. // node.
  32. // params:
  33. // Hash of parameters
  34. // node:
  35. // The draggable node
  36. //console.log("dojox.mdnd.Moveable ::: constructor");
  37. this.node = dojo.byId(node);
  38. this.d = this.node.ownerDocument;
  39. if(!params){ params = {}; }
  40. this.handle = params.handle ? dojo.byId(params.handle) : null;
  41. if(!this.handle){ this.handle = this.node; }
  42. this.skip = params.skip;
  43. this.events = [
  44. dojo.connect(this.handle, "onmousedown", this, "onMouseDown")
  45. ];
  46. if(dojox.mdnd.autoScroll){
  47. this.autoScroll = dojox.mdnd.autoScroll;
  48. }
  49. },
  50. isFormElement: function(/*DOMEvent*/ e){
  51. // summary:
  52. // identify the type of target node associated with a DOM event.
  53. // e:
  54. // a DOM event
  55. // returns:
  56. // if true, the target is one of those specific nodes.
  57. //console.log("dojox.mdnd.Moveable ::: isFormElement");
  58. var t = e.target;
  59. if(t.nodeType == 3 /*TEXT_NODE*/){
  60. t = t.parentNode;
  61. }
  62. return " a button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0; // Boolean
  63. },
  64. onMouseDown: function(/*DOMEvent*/e){
  65. // summary:
  66. // Occurs when the user clicks on the handle node.
  67. // Skip the drag action if a specific node is targeted.
  68. // Listens to mouseup and mousemove events on to the HTML document.
  69. // e:
  70. // a DOM event
  71. // tags:
  72. // callback
  73. //console.log("dojox.mdnd.Moveable ::: onMouseDown");
  74. if(this._isDragging){ return;}
  75. var isLeftButton = (e.which || e.button) == 1;
  76. if(!isLeftButton){
  77. return;
  78. }
  79. if(this.skip && this.isFormElement(e)){ return; }
  80. if(this.autoScroll){
  81. this.autoScroll.setAutoScrollNode(this.node);
  82. this.autoScroll.setAutoScrollMaxPage();
  83. }
  84. this.events.push(dojo.connect(this.d, "onmouseup", this, "onMouseUp"));
  85. this.events.push(dojo.connect(this.d, "onmousemove", this, "onFirstMove"));
  86. this._selectStart = dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent);
  87. this._firstX = e.clientX;
  88. this._firstY = e.clientY;
  89. dojo.stopEvent(e);
  90. },
  91. onFirstMove: function(/*DOMEvent*/e){
  92. // summary:
  93. // Occurs when the user moves the mouse after clicking on the
  94. // handle.
  95. // Determinate when the drag action will have to begin (see
  96. // dragDistance).
  97. // e:
  98. // A DOM event
  99. // tags:
  100. // callback
  101. //console.log("dojox.mdnd.Moveable ::: onFirstMove");
  102. dojo.stopEvent(e);
  103. var d = (this._firstX - e.clientX) * (this._firstX - e.clientX)
  104. + (this._firstY - e.clientY) * (this._firstY - e.clientY);
  105. if(d > this.dragDistance * this.dragDistance){
  106. this._isDragging = true;
  107. dojo.disconnect(this.events.pop());
  108. dojo.style(this.node, "width", dojo.contentBox(this.node).w + "px");
  109. this.initOffsetDrag(e);
  110. this.events.push(dojo.connect(this.d, "onmousemove", this, "onMove"));
  111. }
  112. },
  113. initOffsetDrag: function(/*DOMEvent*/e){
  114. // summary:
  115. // Initialize the gap between main node coordinates and the clicked point.
  116. // Call the onDragStart method.
  117. // e:
  118. // A DOM event
  119. //console.log("dojox.mdnd.Moveable ::: initOffsetDrag");
  120. this.offsetDrag = { 'l': e.pageX, 't': e.pageY };
  121. var s = this.node.style;
  122. var position = dojo.position(this.node, true);
  123. /*if(s.position == "relative" || s.position == ""){
  124. s.position = "absolute"; // enforcing the absolute mode
  125. }*/
  126. this.offsetDrag.l = position.x - this.offsetDrag.l;
  127. this.offsetDrag.t = position.y - this.offsetDrag.t;
  128. var coords = {
  129. 'x': position.x,
  130. 'y': position.y
  131. };
  132. this.size = {
  133. 'w': position.w,
  134. 'h': position.h
  135. };
  136. // method to catch
  137. this.onDragStart(this.node, coords, this.size);
  138. },
  139. onMove: function(/*DOMEvent*/e){
  140. // summary:
  141. // Occurs when the user moves the mouse.
  142. // Calls the onDrag method.
  143. // e:
  144. // a DOM event
  145. // tags:
  146. // callback
  147. //console.log("dojox.mdnd.Moveable ::: onMove");
  148. dojo.stopEvent(e);
  149. // hack to avoid too many calls to onMove in IE8 causing sometimes slowness
  150. if(dojo.isIE == 8 && new Date() - this.date < 20){
  151. return;
  152. }
  153. if(this.autoScroll){
  154. this.autoScroll.checkAutoScroll(e);
  155. }
  156. var coords = {
  157. 'x': this.offsetDrag.l + e.pageX,
  158. 'y': this.offsetDrag.t + e.pageY
  159. };
  160. var s = this.node.style;
  161. s.left = coords.x + "px";
  162. s.top = coords.y + "px";
  163. // method to catch
  164. this.onDrag(this.node, coords, this.size, {'x':e.pageX, 'y':e.pageY});
  165. if(dojo.isIE == 8){
  166. this.date = new Date();
  167. }
  168. },
  169. onMouseUp: function(/*DOMEvent*/e){
  170. // summary:
  171. // Occurs when the user releases the mouse
  172. // Calls the onDragEnd method.
  173. // e:
  174. // a DOM event
  175. if (this._isDragging){
  176. dojo.stopEvent(e);
  177. this._isDragging = false;
  178. if(this.autoScroll){
  179. this.autoScroll.stopAutoScroll();
  180. }
  181. delete this.onMove;
  182. this.onDragEnd(this.node);
  183. this.node.focus();
  184. }
  185. dojo.disconnect(this.events.pop());
  186. dojo.disconnect(this.events.pop());
  187. },
  188. onDragStart: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size){
  189. // summary:
  190. // Stub function.
  191. // Notes : border box model
  192. // node:
  193. // a DOM node
  194. // coords:
  195. // absolute position of the main node
  196. // size:
  197. // an object encapsulating width an height values
  198. // tags:
  199. // callback
  200. },
  201. onDragEnd: function(/*DOMNode*/node){
  202. // summary:
  203. // Stub function
  204. // Notes : Coordinates don't contain margins
  205. // node:
  206. // a DOM node
  207. // tags:
  208. // callback
  209. },
  210. onDrag: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size, /*Object*/mousePosition){
  211. // summary:
  212. // Stub function.
  213. // Notes : border box model for size value, margin box model for coordinates
  214. // node:
  215. // a DOM node
  216. // coords:
  217. // position of the main node (equals to css left/top properties)
  218. // size:
  219. // an object encapsulating width and height values
  220. // mousePosition:
  221. // coordiantes of mouse
  222. // tags:
  223. // callback
  224. },
  225. destroy: function(){
  226. // summary:
  227. // Delecte associated events
  228. // console.log("dojox.mdnd.Moveable ::: destroy");
  229. dojo.forEach(this.events, dojo.disconnect);
  230. this.events = this.node = null;
  231. }
  232. });
  233. });