本文共 8179 字,大约阅读时间需要 27 分钟。
Drag Arrange Example Example 2
/** * drag-shift * http://github.com/vishalok12 * Copyright (c) 2014 Vishal Kumar * Licensed under the MIT License. */'use strict';(function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else { // Browser globals factory(jQuery); }}(function ($) { var IS_TOUCH_DEVICE = ('ontouchstart' in document.documentElement); /** * mouse move threshold (in px) until drag action starts * @type {Number} */ var DRAG_THRESHOLD = 5; /** * to generate event namespace * @type {Number} */ var counter = 0; /** * Javascript events for touch device/desktop * @return {Object} */ 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; // client(X|Y) position before drag starts var $elements; // list of elements to shift between var touchDown = false; var leftOffset, topOffset; var eventNamespace; if (typeof options === "string") { // check if want to destroy drag-arrange if (options === 'destroy') { if (this.eq(0).data('drag-arrange-destroy')) { this.eq(0).data('drag-arrange-destroy')(); } return this; } } options = $.extend({}, options); $elements = this; eventNamespace = getEventNamespace(); this.each(function() { // bindings to trigger drag on element 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) { // a mouse down/touchstart event, but still drag doesn't start till threshold reaches // stopPropagation is compulsory, otherwise touchmove fires only once (android < 4 issue) e.stopPropagation(); touchDown = true; originalClientX = e.clientX || e.originalEvent.touches[0].clientX; originalClientY = e.clientY || e.originalEvent.touches[0].clientY; dragElement = self; } }); // bind mouse-move/touchmove on document // (as it is not compulsory that event will trigger on dragging element) $(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); // check for drag threshold (drag has not started yet) } else if (Math.abs(dragDistanceX) > DRAG_THRESHOLD || Math.abs(dragDistanceY) > DRAG_THRESHOLD) { $clone = clone($dragElement); // initialize left offset and top offset // will be used in successive calls of this function 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')); // put cloned element just above the dragged element // and move it instead of original element $clone.css({ left: leftOffset, top: topOffset }); $dragElement.parent().append($clone); // hide original dragged element $dragElement.css('visibility', 'hidden'); dragging = true; } } function dragEndHandler(e) { if (dragging) { // remove the cloned dragged element and // show original element back e.stopPropagation(); dragging = false; $clone.remove(); dragElement.style.visibility = 'visible'; } touchDown = false; } function destroy() { $elements.each(function() { // bindings to trigger drag on element 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); // remove data $elements.eq(0).data('drag-arrange-destroy', null); // clear variables $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 // very high value to prevent it to hide below other element(s) }); return $clone; } /** * find the element on which the dragged element is hovering * @return {DOM Object} hovered element */ 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(); // current element width and draggable element(clone) width or height can be different horizontalMidPosition = offset.left + 0.5 * $currentElement.width(); verticalMidPosition = offset.top + 0.5 * $currentElement.height(); // check if this element position is overlapping with dragged element 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]) { // shift all other elements to make space for the dragged element var hoveredElementIndex = $movableElements.index(hoveredElement); var dragElementIndex = $movableElements.index($dragElement); if (hoveredElementIndex < dragElementIndex) { $(hoveredElement).before($dragElement); } else { $(hoveredElement).after($dragElement); } // since elements order have changed, need to change order in jQuery Object too 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; }}));
资源:http://download.csdn.net/detail/shiyuezhong/9827842
转载地址:http://aihji.baihongyu.com/