Greasy Fork is available in English.

jquery.udraggable

jQuery udraggable plugin

Questo script non dovrebbe essere installato direttamente. È una libreria per altri script da includere con la chiave // @require https://update.greatest.deepsurf.us/scripts/6422/24599/jqueryudraggable.js

  1. /*
  2. * jQuery udraggable plugin v0.3.0
  3. * Copyright (c) 2013-2014 Grant McLean (grant@mclean.net.nz)
  4. *
  5. * Homepage: https://github.com/grantm/jquery-udraggable
  6. *
  7. * Dual licensed under the MIT and GPL (v2.0 or later) licenses:
  8. * http://opensource.org/licenses/MIT
  9. * http://opensource.org/licenses/GPL-2.0
  10. *
  11. * This library requires Michael S. Mikowski's unified mouse and touch
  12. * event plugin: https://github.com/mmikowski/jquery.event.ue
  13. *
  14. */
  15.  
  16. (function($) {
  17. "use strict";
  18.  
  19. var floor = Math.floor;
  20. var min = Math.min;
  21. var max = Math.max;
  22.  
  23. window.requestAnimationFrame = window.requestAnimationFrame || function(work) {
  24. return setTimeout(work, 10);
  25. };
  26.  
  27. window.cancelAnimationFrame = window.cancelAnimationFrame || function(id) {
  28. return clearTimeout(id);
  29. };
  30.  
  31.  
  32. // Constructor function
  33.  
  34. var UDraggable = function (el, options) {
  35. var that = this;
  36. this.el = el;
  37. this.$el = $(el);
  38. this.options = $.extend({}, $.fn.udraggable.defaults, options);
  39. this.positionElement = this.options.positionElement || this.positionElement;
  40. this.getStartPosition = this.options.getStartPosition || this.getStartPosition;
  41. this.updatePositionFrameHandler = function() {
  42. delete that.queuedUpdate;
  43. var pos = that.ui.position;
  44. that.positionElement(that.$el, that.started, pos.left, pos.top);
  45. if (that.options.dragUpdate) {
  46. that.options.dragUpdate.apply(that.el, [that.ui]);
  47. }
  48. };
  49. this.queuePositionUpdate = function() {
  50. if (!that.queuedUpdate) {
  51. that.queuedUpdate = window.requestAnimationFrame(that.updatePositionFrameHandler);
  52. }
  53. };
  54. this.init();
  55. };
  56.  
  57. UDraggable.prototype = {
  58.  
  59. constructor: UDraggable,
  60.  
  61. init: function() {
  62. var that = this;
  63. this.disabled = false;
  64. this.started = false;
  65. this.normalisePosition();
  66. var $target = this.options.handle ?
  67. this.$el.find( this.options.handle ) :
  68. this.$el;
  69. if (this.options.longPress) {
  70. $target
  71. .on('uheldstart.udraggable', function(e) { that.start(e); })
  72. .on('uheldmove.udraggable', function(e) { that.move(e); })
  73. .on('uheldend.udraggable', function(e) { that.end(e); });
  74. }
  75. else {
  76. $target
  77. .on('udragstart.udraggable', function(e) { that.start(e); })
  78. .on('udragmove.udraggable', function(e) { that.move(e); })
  79. .on('udragend.udraggable', function(e) { that.end(e); });
  80. }
  81. },
  82.  
  83. destroy: function() {
  84. var $target = this.options.handle ?
  85. this.$el.find( this.options.handle ) :
  86. this.$el;
  87. $target.off('.udraggable');
  88. this.$el.removeData('udraggable');
  89. },
  90.  
  91. disable: function() {
  92. this.disabled = true;
  93. },
  94.  
  95. enable: function() {
  96. this.disabled = false;
  97. },
  98.  
  99. option: function() {
  100. var name;
  101. if (arguments.length === 0) {
  102. return this.options;
  103. }
  104. if (arguments.length === 2) {
  105. this.options[ arguments[0] ] = arguments[1];
  106. return;
  107. }
  108. if (arguments.length === 1) {
  109. if (typeof arguments[0] === 'string') {
  110. return this.options[ arguments[0] ];
  111. }
  112. if (typeof arguments[0] === 'object') {
  113. for(name in arguments[0]) {
  114. if (arguments[0].hasOwnProperty(name)) {
  115. this.options[name] = arguments[0][name];
  116. }
  117. }
  118. }
  119. }
  120. if (this.options.containment) {
  121. this._initContainment();
  122. }
  123. },
  124.  
  125. normalisePosition: function() {
  126. var pos = this.$el.position();
  127. this.$el.css({
  128. position: 'absolute',
  129. top: pos.top,
  130. left: pos.left,
  131. right: 'auto',
  132. bottom: 'auto'
  133. });
  134. },
  135.  
  136. start: function(e) {
  137. if (this.disabled) {
  138. return;
  139. }
  140. var start = this.getStartPosition(this.$el);
  141. this._initContainment();
  142. this.ui = {
  143. helper: this.$el,
  144. offset: { top: start.y, left: start.x},
  145. originalPosition: { top: start.y, left: start.x},
  146. position: { top: start.y, left: start.x},
  147. };
  148. if (this.options.longPress) {
  149. this._start(e);
  150. }
  151. return this._stopPropagation(e);
  152. },
  153.  
  154. move: function(e) {
  155. if (this.disabled || (!this.started && !this._start(e))) {
  156. return;
  157. }
  158. var delta_x = e.px_current_x - e.px_start_x;
  159. var delta_y = e.px_current_y - e.px_start_y;
  160. var axis = this.options.axis;
  161. if (axis && axis === "x") {
  162. delta_y = 0;
  163. }
  164. if (axis && axis === "y") {
  165. delta_x = 0;
  166. }
  167. var cur = {
  168. left: this.ui.originalPosition.left,
  169. top: this.ui.originalPosition.top
  170. };
  171. if (!axis || (axis === "x")) {
  172. cur.left += delta_x;
  173. }
  174. if (!axis || (axis === "y")) {
  175. cur.top += delta_y;
  176. }
  177. this._applyGrid(cur);
  178. this._applyContainment(cur);
  179. var pos = this.ui.position;
  180. if ((cur.top !== pos.top) || (cur.left !== pos.left)) {
  181. this.ui.position.left = cur.left;
  182. this.ui.position.top = cur.top;
  183. this.ui.offset.left = cur.left;
  184. this.ui.offset.top = cur.top;
  185. if (this.options.drag) {
  186. this.options.drag.apply(this.el, [e, this.ui]);
  187. }
  188. this.queuePositionUpdate();
  189. }
  190. return this._stopPropagation(e);
  191. },
  192.  
  193. end: function(e) {
  194. if (this.started || this._start(e)) {
  195. this.$el.removeClass("udraggable-dragging");
  196. this.started = false;
  197. if (this.queuedUpdate) {
  198. window.cancelAnimationFrame(this.queuedUpdate);
  199. }
  200. this.updatePositionFrameHandler();
  201. if (this.options.stop) {
  202. this.options.stop.apply(this.el, [e, this.ui]);
  203. }
  204. }
  205. return this._stopPropagation(e);
  206. },
  207.  
  208. // helper methods
  209.  
  210. _stopPropagation: function(e) {
  211. e.stopPropagation();
  212. e.preventDefault();
  213. return false;
  214. },
  215.  
  216. _start: function(e) {
  217. if (!this._mouseDistanceMet(e) || !this._mouseDelayMet(e)) {
  218. return;
  219. }
  220. this.started = true;
  221. this.queuePositionUpdate();
  222. if (this.options.start) {
  223. this.options.start.apply(this.el, [e, this.ui]);
  224. }
  225. this.$el.addClass("udraggable-dragging");
  226. return true;
  227. },
  228.  
  229. _mouseDistanceMet: function(e) {
  230. return max(
  231. Math.abs(e.px_start_x - e.px_current_x),
  232. Math.abs(e.px_start_y - e.px_current_y)
  233. ) >= this.options.distance;
  234. },
  235.  
  236. _mouseDelayMet: function(e) {
  237. return e.ms_elapsed > this.options.delay;
  238. },
  239.  
  240. _initContainment: function() {
  241. var o = this.options;
  242. var $c, ce;
  243.  
  244. if (!o.containment) {
  245. this.containment = null;
  246. return;
  247. }
  248.  
  249. if (o.containment.constructor === Array) {
  250. this.containment = o.containment;
  251. return;
  252. }
  253.  
  254. if (o.containment === "parent") {
  255. o.containment = this.$el.offsetParent();
  256. }
  257.  
  258. $c = $( o.containment );
  259. ce = $c[ 0 ];
  260. if (!ce) {
  261. return;
  262. }
  263.  
  264. this.containment = [
  265. 0,
  266. 0,
  267. $c.innerWidth() - this.$el.outerWidth(),
  268. $c.innerHeight() - this.$el.outerHeight(),
  269. ];
  270. },
  271.  
  272. _applyGrid: function(cur) {
  273. if (this.options.grid) {
  274. var gx = this.options.grid[0];
  275. var gy = this.options.grid[1];
  276. cur.left = floor( (cur.left + gx / 2) / gx ) * gx;
  277. cur.top = floor( (cur.top + gy / 2) / gy ) * gy;
  278. }
  279. },
  280.  
  281. _applyContainment: function(cur) {
  282. var cont = this.containment;
  283. if (cont) {
  284. cur.left = min( max(cur.left, cont[0]), cont[2] );
  285. cur.top = min( max(cur.top, cont[1]), cont[3] );
  286. }
  287. },
  288.  
  289. getStartPosition: function($el) {
  290. return {
  291. x: parseInt($el.css('left'), 10) || 0,
  292. y: parseInt($el.css('top'), 10) || 0
  293. };
  294. },
  295.  
  296. positionElement: function($el, dragging, left, top) {
  297. $el.css({ left: left, top: top });
  298. }
  299.  
  300. };
  301.  
  302.  
  303. // jQuery plugin function
  304.  
  305. $.fn.udraggable = function(option) {
  306. var args = Array.prototype.slice.call(arguments, 1);
  307. var results = [];
  308. this.each(function () {
  309. var $this = $(this);
  310. var data = $this.data('udraggable');
  311. if (!data) {
  312. data = new UDraggable(this, option);
  313. $this.data('udraggable', data);
  314. }
  315. if (typeof option === 'string') { // option is a method - call it
  316. if(typeof data[option] !== 'function') {
  317. throw "jquery.udraggable has no '" + option + "' method";
  318. }
  319. var result = data[option].apply(data, args);
  320. if (result !== undefined) {
  321. results.push( result );
  322. }
  323. }
  324. });
  325. return results.length > 0 ? results[0] : this;
  326. };
  327.  
  328. $.fn.udraggable.defaults = {
  329. axis: null,
  330. delay: 0,
  331. distance: 0,
  332. longPress: false,
  333. // callbacks
  334. drag: null,
  335. start: null,
  336. stop: null
  337. };
  338.  
  339.  
  340. })(jQuery);
  341.