vue-dragging.es5.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /*!
  2. * Awe-dnd v0.3.2
  3. * (c) 2018 Awe <hilongjw@gmail.com>
  4. * Released under the MIT License.
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global.VueDragging = factory());
  10. }(this, (function () { 'use strict';
  11. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  12. function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
  13. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14. var DragData = function () {
  15. function DragData() {
  16. _classCallCheck(this, DragData);
  17. this.data = {};
  18. }
  19. _createClass(DragData, [{
  20. key: 'new',
  21. value: function _new(key) {
  22. if (!this.data[key]) {
  23. this.data[key] = {
  24. className: '',
  25. List: [],
  26. KEY_MAP: {}
  27. };
  28. }
  29. return this.data[key];
  30. }
  31. }, {
  32. key: 'get',
  33. value: function get(key) {
  34. return this.data[key];
  35. }
  36. }]);
  37. return DragData;
  38. }();
  39. var $dragging = {
  40. listeners: {},
  41. $on: function $on(event, func) {
  42. var events = this.listeners[event];
  43. if (!events) {
  44. this.listeners[event] = [];
  45. }
  46. this.listeners[event].push(func);
  47. },
  48. $once: function $once(event, func) {
  49. var vm = this;
  50. function on() {
  51. vm.$off(event, on);
  52. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  53. args[_key] = arguments[_key];
  54. }
  55. func.apply(vm, args);
  56. }
  57. this.$on(event, on);
  58. },
  59. $off: function $off(event, func) {
  60. var events = this.listeners[event];
  61. if (!func || !events) {
  62. this.listeners[event] = [];
  63. return;
  64. }
  65. this.listeners[event] = this.listeners[event].filter(function (i) {
  66. return i !== func;
  67. });
  68. },
  69. $emit: function $emit(event, context) {
  70. var events = this.listeners[event];
  71. if (events && events.length > 0) {
  72. events.forEach(function (func) {
  73. func(context);
  74. });
  75. }
  76. }
  77. };
  78. var _ = {
  79. on: function on(el, type, fn) {
  80. el.addEventListener(type, fn);
  81. },
  82. off: function off(el, type, fn) {
  83. el.removeEventListener(type, fn);
  84. },
  85. addClass: function addClass(el, cls) {
  86. if (arguments.length < 2) {
  87. el.classList.add(cls);
  88. } else {
  89. for (var i = 1, len = arguments.length; i < len; i++) {
  90. el.classList.add(arguments[i]);
  91. }
  92. }
  93. },
  94. removeClass: function removeClass(el, cls) {
  95. if (arguments.length < 2) {
  96. el.classList.remove(cls);
  97. } else {
  98. for (var i = 1, len = arguments.length; i < len; i++) {
  99. el.classList.remove(arguments[i]);
  100. }
  101. }
  102. }
  103. };
  104. var vueDragging = function (Vue, options) {
  105. var isPreVue = Vue.version.split('.')[0] === '1';
  106. var dragData = new DragData();
  107. var isSwap = false;
  108. var Current = null;
  109. function handleDragStart(e) {
  110. var el = getBlockEl(e.target);
  111. var key = el.getAttribute('drag_group');
  112. var drag_key = el.getAttribute('drag_key');
  113. var comb = el.getAttribute('comb');
  114. var DDD = dragData.new(key);
  115. var item = DDD.KEY_MAP[drag_key];
  116. var index = DDD.List.indexOf(item);
  117. var groupArr = DDD.List.filter(function (item) {
  118. return item[comb];
  119. });
  120. _.addClass(el, 'dragging');
  121. if (e.dataTransfer) {
  122. e.dataTransfer.effectAllowed = 'move';
  123. e.dataTransfer.setData('text', JSON.stringify(item));
  124. }
  125. Current = {
  126. index: index,
  127. item: item,
  128. el: el,
  129. group: key,
  130. groupArr: groupArr
  131. };
  132. }
  133. function handleDragOver(e) {
  134. if (e.preventDefault) {
  135. e.preventDefault();
  136. }
  137. return false;
  138. }
  139. function handleDragEnter(e) {
  140. var el = void 0;
  141. if (e.type === 'touchmove') {
  142. e.stopPropagation();
  143. e.preventDefault();
  144. el = getOverElementFromTouch(e);
  145. el = getBlockEl(el);
  146. } else {
  147. el = getBlockEl(e.target);
  148. }
  149. if (!el || !Current) return;
  150. var key = el.getAttribute('drag_group');
  151. if (key !== Current.group || !Current.el || !Current.item || el === Current.el) return;
  152. var drag_key = el.getAttribute('drag_key');
  153. var DDD = dragData.new(key);
  154. var item = DDD.KEY_MAP[drag_key];
  155. if (item === Current.item) return;
  156. var indexTo = DDD.List.indexOf(item);
  157. var indexFrom = DDD.List.indexOf(Current.item);
  158. swapArrayElements(DDD.List, indexFrom, indexTo);
  159. Current.groupArr.forEach(function (item) {
  160. if (item != Current.item) {
  161. DDD.List.splice(DDD.List.indexOf(item), 1);
  162. }
  163. });
  164. var targetIndex = DDD.List.indexOf(Current.item);
  165. if (Current.groupArr.length) {
  166. var _DDD$List;
  167. (_DDD$List = DDD.List).splice.apply(_DDD$List, [targetIndex, 1].concat(_toConsumableArray(Current.groupArr)));
  168. }
  169. Current.index = indexTo;
  170. isSwap = true;
  171. $dragging.$emit('dragged', {
  172. draged: Current.item,
  173. to: item,
  174. value: DDD.value,
  175. group: key
  176. });
  177. }
  178. function handleDragLeave(e) {
  179. _.removeClass(getBlockEl(e.target), 'drag-over', 'drag-enter');
  180. }
  181. function handleDrag(e) {}
  182. function handleDragEnd(e) {
  183. var el = getBlockEl(e.target);
  184. _.removeClass(el, 'dragging', 'drag-over', 'drag-enter');
  185. Current = null;
  186. // if (isSwap) {
  187. isSwap = false;
  188. var group = el.getAttribute('drag_group');
  189. $dragging.$emit('dragend', { group: group });
  190. // }
  191. }
  192. function handleDrop(e) {
  193. e.preventDefault();
  194. if (e.stopPropagation) {
  195. e.stopPropagation();
  196. }
  197. return false;
  198. }
  199. function getBlockEl(el) {
  200. if (!el) return;
  201. while (el.parentNode) {
  202. if (el.getAttribute && el.getAttribute('drag_block')) {
  203. return el;
  204. break;
  205. } else {
  206. el = el.parentNode;
  207. }
  208. }
  209. }
  210. function swapArrayElements(items, indexFrom, indexTo) {
  211. var item = items[indexTo];
  212. if (isPreVue) {
  213. items.$set(indexTo, items[indexFrom]);
  214. items.$set(indexFrom, item);
  215. } else {
  216. Vue.set(items, indexTo, items[indexFrom]);
  217. Vue.set(items, indexFrom, item);
  218. }
  219. return items;
  220. }
  221. function getOverElementFromTouch(e) {
  222. var touch = e.touches[0];
  223. var el = document.elementFromPoint(touch.clientX, touch.clientY);
  224. return el;
  225. }
  226. function addDragItem(el, binding, vnode) {
  227. var item = binding.value.item;
  228. var list = binding.value.list;
  229. var DDD = dragData.new(binding.value.group);
  230. var drag_key = isPreVue ? binding.value.key : vnode.key;
  231. DDD.value = binding.value;
  232. DDD.className = binding.value.className;
  233. DDD.KEY_MAP[drag_key] = item;
  234. if (list && DDD.List !== list) {
  235. DDD.List = list;
  236. }
  237. el.setAttribute('draggable', 'true');
  238. el.setAttribute('drag_group', binding.value.group);
  239. el.setAttribute('drag_block', binding.value.group);
  240. el.setAttribute('drag_key', drag_key);
  241. el.setAttribute('comb', binding.value.comb);
  242. _.on(el, 'dragstart', handleDragStart);
  243. _.on(el, 'dragenter', handleDragEnter);
  244. _.on(el, 'dragover', handleDragOver);
  245. _.on(el, 'drag', handleDrag);
  246. _.on(el, 'dragleave', handleDragLeave);
  247. _.on(el, 'dragend', handleDragEnd);
  248. _.on(el, 'drop', handleDrop);
  249. _.on(el, 'touchstart', handleDragStart);
  250. _.on(el, 'touchmove', handleDragEnter);
  251. _.on(el, 'touchend', handleDragEnd);
  252. }
  253. function removeDragItem(el, binding, vnode) {
  254. var DDD = dragData.new(binding.value.group);
  255. var drag_key = isPreVue ? binding.value.key : vnode.key;
  256. DDD.KEY_MAP[drag_key] = undefined;
  257. _.off(el, 'dragstart', handleDragStart);
  258. _.off(el, 'dragenter', handleDragEnter);
  259. _.off(el, 'dragover', handleDragOver);
  260. _.off(el, 'drag', handleDrag);
  261. _.off(el, 'dragleave', handleDragLeave);
  262. _.off(el, 'dragend', handleDragEnd);
  263. _.off(el, 'drop', handleDrop);
  264. _.off(el, 'touchstart', handleDragStart);
  265. _.off(el, 'touchmove', handleDragEnter);
  266. _.off(el, 'touchend', handleDragEnd);
  267. }
  268. Vue.prototype.$dragging = $dragging;
  269. if (!isPreVue) {
  270. Vue.directive('dragging', {
  271. bind: addDragItem,
  272. update: function update(el, binding, vnode) {
  273. var DDD = dragData.new(binding.value.group);
  274. var item = binding.value.item;
  275. var list = binding.value.list;
  276. var drag_key = vnode.key;
  277. var old_item = DDD.KEY_MAP[drag_key];
  278. if (item && old_item !== item) {
  279. DDD.KEY_MAP[drag_key] = item;
  280. }
  281. if (list && DDD.List !== list) {
  282. DDD.List = list;
  283. }
  284. },
  285. unbind: removeDragItem
  286. });
  287. } else {
  288. Vue.directive('dragging', {
  289. update: function update(newValue, oldValue) {
  290. addDragItem(this.el, {
  291. modifiers: this.modifiers,
  292. arg: this.arg,
  293. value: newValue,
  294. oldValue: oldValue
  295. });
  296. },
  297. unbind: function unbind(newValue, oldValue) {
  298. removeDragItem(this.el, {
  299. modifiers: this.modifiers,
  300. arg: this.arg,
  301. value: newValue ? newValue : { group: this.el.getAttribute('drag_group') },
  302. oldValue: oldValue
  303. });
  304. }
  305. });
  306. }
  307. };
  308. return vueDragging;
  309. })));