Moveable.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojo.dnd.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojo.dnd.Moveable"] = true;
  8. dojo.provide("dojo.dnd.Moveable");
  9. dojo.require("dojo.dnd.Mover");
  10. /*=====
  11. dojo.declare("dojo.dnd.__MoveableArgs", [], {
  12. // handle: Node||String
  13. // A node (or node's id), which is used as a mouse handle.
  14. // If omitted, the node itself is used as a handle.
  15. handle: null,
  16. // delay: Number
  17. // delay move by this number of pixels
  18. delay: 0,
  19. // skip: Boolean
  20. // skip move of form elements
  21. skip: false,
  22. // mover: Object
  23. // a constructor of custom Mover
  24. mover: dojo.dnd.Mover
  25. });
  26. =====*/
  27. dojo.declare("dojo.dnd.Moveable", null, {
  28. // object attributes (for markup)
  29. handle: "",
  30. delay: 0,
  31. skip: false,
  32. constructor: function(node, params){
  33. // summary:
  34. // an object, which makes a node moveable
  35. // node: Node
  36. // a node (or node's id) to be moved
  37. // params: dojo.dnd.__MoveableArgs?
  38. // optional parameters
  39. this.node = dojo.byId(node);
  40. if(!params){ params = {}; }
  41. this.handle = params.handle ? dojo.byId(params.handle) : null;
  42. if(!this.handle){ this.handle = this.node; }
  43. this.delay = params.delay > 0 ? params.delay : 0;
  44. this.skip = params.skip;
  45. this.mover = params.mover ? params.mover : dojo.dnd.Mover;
  46. this.events = [
  47. dojo.connect(this.handle, "onmousedown", this, "onMouseDown"),
  48. dojo.connect(this.handle, "ontouchstart", this, "onMouseDown"),
  49. // cancel text selection and text dragging
  50. dojo.connect(this.handle, "ondragstart", this, "onSelectStart"),
  51. dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
  52. ];
  53. },
  54. // markup methods
  55. markupFactory: function(params, node){
  56. return new dojo.dnd.Moveable(node, params);
  57. },
  58. // methods
  59. destroy: function(){
  60. // summary:
  61. // stops watching for possible move, deletes all references, so the object can be garbage-collected
  62. dojo.forEach(this.events, dojo.disconnect);
  63. this.events = this.node = this.handle = null;
  64. },
  65. // mouse event processors
  66. onMouseDown: function(e){
  67. // summary:
  68. // event processor for onmousedown/ontouchstart, creates a Mover for the node
  69. // e: Event
  70. // mouse/touch event
  71. if(this.skip && dojo.dnd.isFormElement(e)){ return; }
  72. if(this.delay){
  73. this.events.push(
  74. dojo.connect(this.handle, "onmousemove", this, "onMouseMove"),
  75. dojo.connect(this.handle, "ontouchmove", this, "onMouseMove"),
  76. dojo.connect(this.handle, "onmouseup", this, "onMouseUp"),
  77. dojo.connect(this.handle, "ontouchend", this, "onMouseUp")
  78. );
  79. var pos = e.touches ? e.touches[0] : e;
  80. this._lastX = pos.pageX;
  81. this._lastY = pos.pageY;
  82. }else{
  83. this.onDragDetected(e);
  84. }
  85. dojo.stopEvent(e);
  86. },
  87. onMouseMove: function(e){
  88. // summary:
  89. // event processor for onmousemove/ontouchmove, used only for delayed drags
  90. // e: Event
  91. // mouse/touch event
  92. var pos = e.touches ? e.touches[0] : e;
  93. if(Math.abs(pos.pageX - this._lastX) > this.delay || Math.abs(pos.pageY - this._lastY) > this.delay){
  94. this.onMouseUp(e);
  95. this.onDragDetected(e);
  96. }
  97. dojo.stopEvent(e);
  98. },
  99. onMouseUp: function(e){
  100. // summary:
  101. // event processor for onmouseup, used only for delayed drags
  102. // e: Event
  103. // mouse event
  104. for(var i = 0; i < 2; ++i){
  105. dojo.disconnect(this.events.pop());
  106. }
  107. dojo.stopEvent(e);
  108. },
  109. onSelectStart: function(e){
  110. // summary:
  111. // event processor for onselectevent and ondragevent
  112. // e: Event
  113. // mouse event
  114. if(!this.skip || !dojo.dnd.isFormElement(e)){
  115. dojo.stopEvent(e);
  116. }
  117. },
  118. // local events
  119. onDragDetected: function(/* Event */ e){
  120. // summary:
  121. // called when the drag is detected;
  122. // responsible for creation of the mover
  123. new this.mover(this.node, e, this);
  124. },
  125. onMoveStart: function(/* dojo.dnd.Mover */ mover){
  126. // summary:
  127. // called before every move operation
  128. dojo.publish("/dnd/move/start", [mover]);
  129. dojo.addClass(dojo.body(), "dojoMove");
  130. dojo.addClass(this.node, "dojoMoveItem");
  131. },
  132. onMoveStop: function(/* dojo.dnd.Mover */ mover){
  133. // summary:
  134. // called after every move operation
  135. dojo.publish("/dnd/move/stop", [mover]);
  136. dojo.removeClass(dojo.body(), "dojoMove");
  137. dojo.removeClass(this.node, "dojoMoveItem");
  138. },
  139. onFirstMove: function(/* dojo.dnd.Mover */ mover, /* Event */ e){
  140. // summary:
  141. // called during the very first move notification;
  142. // can be used to initialize coordinates, can be overwritten.
  143. // default implementation does nothing
  144. },
  145. onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){
  146. // summary:
  147. // called during every move notification;
  148. // should actually move the node; can be overwritten.
  149. this.onMoving(mover, leftTop);
  150. var s = mover.node.style;
  151. s.left = leftTop.l + "px";
  152. s.top = leftTop.t + "px";
  153. this.onMoved(mover, leftTop);
  154. },
  155. onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
  156. // summary:
  157. // called before every incremental move; can be overwritten.
  158. // default implementation does nothing
  159. },
  160. onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
  161. // summary:
  162. // called after every incremental move; can be overwritten.
  163. // default implementation does nothing
  164. }
  165. });
  166. }