| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- 'use strict';
- (function (factory) {
- if (typeof define === 'function' && define.amd) {
- define(['jquery'], factory);
- } else {
- factory(jQuery);
- }
- }
- (function ($) {
- var IS_TOUCH_DEVICE = ('ontouchstart' in document.documentElement);
- var DRAG_THRESHOLD = 5;
- var counter = 0;
- var dragEvents = (function () {
- if (IS_TOUCH_DEVICE) {
- return {
- START: 'touchstart',
- MOVE: 'touchmove',
- END: 'touchend'
- };
- } else {
- return {
- START: 'mousedown',
- MOVE: 'mousemove',
- END: 'mouseup'
- };
- }
- }());
- $.fn.arrangeable = function (options) {
- var dragging = false;
- var $clone;
- var dragElement;
- var originalClientX, originalClientY;
- var $elements;
- var touchDown = false;
- var leftOffset, topOffset;
- var eventNamespace;
- var $options = options;
- if (typeof options === "string") {
- if (options === 'destroy') {
- if (this.eq(0).data('drag-arrange-destroy')) {
- this.eq(0).data('drag-arrange-destroy')();
- }
- return this;
- }
- }
- options = $.extend({
- "dragEndEvent": "drag.end.arrangeable"
- }, options);
- var dragEndEvent = options["dragEndEvent"];
- $elements = this;
- eventNamespace = getEventNamespace();
- this.each(function () {
- var dragSelector = options.dragSelector;
- var self = this;
- var $this = $(this);
- if (dragSelector) {
- $this.on(dragEvents.START + eventNamespace,
- dragSelector, dragStartHandler);
- } else {
- $this.on(dragEvents.START + eventNamespace,
- dragStartHandler);
- }
-
- function dragStartHandler(e) {
- e.stopPropagation();
- touchDown = true;
- originalClientX = e.clientX
- || e.originalEvent.touches[0].clientX;
- originalClientY = e.clientY
- || e.originalEvent.touches[0].clientY;
- dragElement = self;
- }
- });
- $(document).on(dragEvents.MOVE + eventNamespace,
- dragMoveHandler).on(dragEvents.END + eventNamespace,
- dragEndHandler);
-
- function dragMoveHandler(e) {
- if (!touchDown) {
- return;
- }
- var $dragElement = $(dragElement);
- var dragDistanceX = (e.clientX || e.originalEvent.touches[0].clientX)
- - originalClientX;
- var dragDistanceY = (e.clientY || e.originalEvent.touches[0].clientY)
- - originalClientY;
- if (dragging) {
- e.stopPropagation();
- $clone.css({
- left: leftOffset + dragDistanceX,
- top: topOffset + dragDistanceY
- });
- shiftHoveredElement($clone, $dragElement, $elements);
- } else if (Math.abs(dragDistanceX) > DRAG_THRESHOLD
- || Math.abs(dragDistanceY) > DRAG_THRESHOLD) {
- $clone = clone($dragElement);
- leftOffset = dragElement.offsetLeft
- - parseInt($dragElement.css('margin-left'))
- - parseInt($dragElement.css('padding-left'));
- topOffset = dragElement.offsetTop
- - parseInt($dragElement.css('margin-top'))
- - parseInt($dragElement.css('padding-top'));
- $clone.css({
- left: leftOffset,
- top: topOffset
- });
- $dragElement.parent().append($clone);
- $dragElement.css('visibility', 'hidden');
- dragging = true;
- }
- }
-
- function dragEndHandler(e) {
- if (dragging) {
-
- e.stopPropagation();
- dragging = false;
- $clone.remove();
- dragElement.style.visibility = 'visible';
- $(dragElement).parent().trigger(dragEndEvent,
- [$(dragElement)]);
-
- //拖拽结束后执行回调,传入当前拖拽的对象
- if ($options.callback) $options.callback($(dragElement));
- }
- touchDown = false;
-
- }
-
- function destroy() {
- $elements.each(function () {
- var dragSelector = options.dragSelector;
- var $this = $(this);
- if (dragSelector) {
- $this.off(dragEvents.START + eventNamespace,
- dragSelector);
- } else {
- $this.off(dragEvents.START + eventNamespace);
- }
- });
- $(document).off(dragEvents.MOVE + eventNamespace).off(
- dragEvents.END + eventNamespace);
- $elements.eq(0).data('drag-arrange-destroy', null);
- $elements = null;
- dragMoveHandler = null;
- dragEndHandler = null;
- }
-
- this.eq(0).data('drag-arrange-destroy', destroy);
-
-
- };
-
- function clone($element) {
- var $clone = $element.clone();
- $clone.css({
- position: 'absolute',
- width: $element.width(),
- height: $element.height(),
- 'z-index': 100000
- });
- return $clone;
- }
-
- function getHoveredElement($clone, $dragElement, $movableElements) {
- var cloneOffset = $clone.offset();
- var cloneWidth = $clone.width();
- var cloneHeight = $clone.height();
- var cloneLeftPosition = cloneOffset.left;
- var cloneRightPosition = cloneOffset.left + cloneWidth;
- var cloneTopPosition = cloneOffset.top;
- var cloneBottomPosition = cloneOffset.top + cloneHeight;
- var $currentElement;
- var horizontalMidPosition, verticalMidPosition;
- var offset, overlappingX, overlappingY, inRange;
- for (var i = 0; i < $movableElements.length; i++) {
- $currentElement = $movableElements.eq(i);
- if ($currentElement[0] === $dragElement[0]) {
- continue;
- }
- offset = $currentElement.offset();
- horizontalMidPosition = offset.left + 0.5
- * $currentElement.width();
- verticalMidPosition = offset.top + 0.5
- * $currentElement.height();
- overlappingX = (horizontalMidPosition < cloneRightPosition)
- && (horizontalMidPosition > cloneLeftPosition);
- overlappingY = (verticalMidPosition < cloneBottomPosition)
- && (verticalMidPosition > cloneTopPosition);
- inRange = overlappingX && overlappingY;
- if (inRange) {
-
- return $currentElement[0];
- }
- }
-
-
- }
-
- function shiftHoveredElement($clone, $dragElement, $movableElements) {
- var hoveredElement = getHoveredElement($clone, $dragElement,
- $movableElements);
- if (hoveredElement !== $dragElement[0]) {
- var hoveredElementIndex = $movableElements
- .index(hoveredElement);
- var dragElementIndex = $movableElements.index($dragElement);
- if (hoveredElementIndex < dragElementIndex) {
- $(hoveredElement).before($dragElement);
- } else {
- $(hoveredElement).after($dragElement);
- }
- shiftElementPosition($movableElements, dragElementIndex,
- hoveredElementIndex);
- }
-
-
- }
-
- function shiftElementPosition(arr, fromIndex, toIndex) {
- var temp = arr.splice(fromIndex, 1)[0];
-
- return arr.splice(toIndex, 0, temp);
- }
-
- function getEventNamespace() {
- counter += 1;
- return '.drag-arrange-' + counter;
- }
- }));
|