sortable-dnd
Advanced tools
Comparing version 0.2.5 to 0.2.6
/*! | ||
* sortable-dnd v0.2.5 | ||
* sortable-dnd v0.2.6 | ||
* open source under the MIT license | ||
@@ -284,3 +284,3 @@ * https://github.com/mfuu/sortable-dnd#readme | ||
function getElement(group, el, onlyEl) { | ||
var children = _toConsumableArray(Array.from(group.children)); // 如果能直接在子元素中找到,返回对应的index | ||
var children = _toConsumableArray(Array.from(group.children)); // If it can be found directly in the child element, return | ||
@@ -294,3 +294,3 @@ | ||
offset: getOffset(children[index]) | ||
}; // children 中无法直接找到对应的dom时,需要向下寻找 | ||
}; // When the dom cannot be found directly in children, need to look down | ||
@@ -407,4 +407,3 @@ for (var i = 0; i < children.length; i++) { | ||
timer && clearTimeout(timer); | ||
immediate && !timer && fn.apply(context, args); // 首次立即触发 | ||
immediate && !timer && fn.apply(context, args); | ||
timer = setTimeout(function () { | ||
@@ -508,2 +507,3 @@ fn.apply(context, args); | ||
value: function init(el, rect) { | ||
var append = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
this.$el = el; | ||
@@ -529,3 +529,3 @@ var _this$options = this.options, | ||
setTransform(this.$el, 'translate3d(0px, 0px, 0px)'); | ||
this.container.appendChild(this.$el); | ||
if (append) this.container.appendChild(this.$el); | ||
css(this.$el, 'transform-origin', this.distance.x / parseInt(this.$el.style.width) * 100 + '% ' + this.distance.y / parseInt(this.$el.style.height) * 100 + '%'); | ||
@@ -582,2 +582,96 @@ } | ||
function AutoScroll() { | ||
if (!window.requestAnimationFrame) { | ||
window.requestAnimationFrame = function (callback) { | ||
return setTimeout(callback, 17); | ||
}; | ||
} | ||
return { | ||
_autoScroll: throttle(function (_this) { | ||
// check if is moving now | ||
if (!(_this.state.sortableDown && _this.state.sortableMove)) return; | ||
var _this$state$sortableM = _this.state.sortableMove, | ||
clientX = _this$state$sortableM.clientX, | ||
clientY = _this$state$sortableM.clientY; | ||
if (clientX === void 0 || clientY === void 0) return; | ||
if (_this.scrollEl === _this.ownerDocument) ; else { | ||
var _this$scrollEl = _this.scrollEl, | ||
scrollTop = _this$scrollEl.scrollTop, | ||
scrollLeft = _this$scrollEl.scrollLeft, | ||
scrollHeight = _this$scrollEl.scrollHeight, | ||
scrollWidth = _this$scrollEl.scrollWidth; | ||
var _getRect = getRect(_this.scrollEl), | ||
top = _getRect.top, | ||
right = _getRect.right, | ||
bottom = _getRect.bottom, | ||
left = _getRect.left, | ||
height = _getRect.height, | ||
width = _getRect.width; | ||
var _this$options = _this.options, | ||
scrollStep = _this$options.scrollStep, | ||
scrollThreshold = _this$options.scrollThreshold; // check direction | ||
var totop = scrollTop > 0 && clientY >= top && clientY <= top + scrollThreshold; | ||
var toleft = scrollLeft > 0 && clientX >= left && clientX <= left + scrollThreshold; | ||
var toright = scrollLeft + width < scrollWidth && clientX <= right && clientX >= right - scrollThreshold; | ||
var tobottom = scrollTop + height < scrollHeight && clientY <= bottom && clientY >= bottom - scrollThreshold; // scroll position | ||
var position = { | ||
x: scrollLeft, | ||
y: scrollTop | ||
}; | ||
if (totop) { | ||
if (toleft) { | ||
// to top-left | ||
position.x = scrollLeft - scrollStep; | ||
} else if (toright) { | ||
// to top-right | ||
position.x = scrollLeft + scrollStep; | ||
} else { | ||
// to top | ||
position.x = scrollLeft; | ||
} | ||
position.y = scrollTop - scrollStep; | ||
} else if (tobottom) { | ||
if (toleft) { | ||
// to bottom-left | ||
position.x = scrollLeft - scrollStep; | ||
} else if (toright) { | ||
// to bottom-right | ||
position.x = scrollLeft + scrollStep; | ||
} else { | ||
// to bottom | ||
position.x = scrollLeft; | ||
} | ||
position.y = scrollTop + scrollStep; | ||
} else if (toleft) { | ||
// to left | ||
position.x = scrollLeft - scrollStep; | ||
position.y = scrollTop; | ||
} else if (toright) { | ||
// to right | ||
position.x = scrollLeft + scrollStep; | ||
position.y = scrollTop; | ||
} // if need to scroll | ||
if (totop || toleft || toright || tobottom) { | ||
requestAnimationFrame(function () { | ||
_this.scrollEl.scrollTo(position.x, position.y); | ||
_this._autoScroll(_this); | ||
}); | ||
} | ||
} | ||
}, 10) | ||
}; | ||
} | ||
function Animation() { | ||
@@ -606,3 +700,3 @@ var animationState = []; | ||
animationState.length = 0; // 重置 | ||
animationState.length = 0; // reset | ||
@@ -633,3 +727,3 @@ children.slice(start, end + 1).forEach(function (child) { | ||
setTransform(el, "translate3d(".concat(left, "px, ").concat(top, "px, 0)")); | ||
el.offsetLeft; // 触发重绘 | ||
el.offsetLeft; // trigger repaint | ||
@@ -650,3 +744,6 @@ setTransition(el, "".concat(animation, "ms")); | ||
return { | ||
_bindEventListener: function _bindEventListener() { | ||
_bindDragEventListener: function _bindDragEventListener() { | ||
this._onDrag = this._onDrag.bind(this); | ||
this._onMove = this._onMove.bind(this); | ||
this._onDrop = this._onDrop.bind(this); | ||
var _this$options = this.options, | ||
@@ -657,13 +754,13 @@ supportPointer = _this$options.supportPointer, | ||
if (supportPointer) { | ||
on(this.rootEl, 'pointerdown', this._onStart); | ||
on(this.rootEl, 'pointerdown', this._onDrag); | ||
} else if (supportTouch) { | ||
on(this.rootEl, 'touchstart', this._onStart); | ||
on(this.rootEl, 'touchstart', this._onDrag); | ||
} else { | ||
on(this.rootEl, 'mousedown', this._onStart); | ||
on(this.rootEl, 'mousedown', this._onDrag); | ||
} | ||
}, | ||
_unbindEventListener: function _unbindEventListener() { | ||
off(this.rootEl, 'pointerdown', this._onStart); | ||
off(this.rootEl, 'touchstart', this._onStart); | ||
off(this.rootEl, 'mousedown', this._onStart); | ||
_unbindDragEventListener: function _unbindDragEventListener() { | ||
off(this.rootEl, 'pointerdown', this._onDrag); | ||
off(this.rootEl, 'touchstart', this._onDrag); | ||
off(this.rootEl, 'mousedown', this._onDrag); | ||
}, | ||
@@ -679,9 +776,2 @@ _bindMoveEvents: function _bindMoveEvents(touch) { | ||
}, | ||
_bindUpEvents: function _bindUpEvents() { | ||
on(this.ownerDocument, 'pointerup', this._onDrop); | ||
on(this.ownerDocument, 'pointercancel', this._onDrop); | ||
on(this.ownerDocument, 'touchend', this._onDrop); | ||
on(this.ownerDocument, 'touchcancel', this._onDrop); | ||
on(this.ownerDocument, 'mouseup', this._onDrop); | ||
}, | ||
_unbindMoveEvents: function _unbindMoveEvents() { | ||
@@ -692,3 +782,3 @@ off(this.ownerDocument, 'pointermove', this._onMove); | ||
}, | ||
_unbindUpEvents: function _unbindUpEvents() { | ||
_unbindDropEvents: function _unbindDropEvents() { | ||
off(this.ownerDocument, 'pointerup', this._onDrop); | ||
@@ -699,2 +789,9 @@ off(this.ownerDocument, 'pointercancel', this._onDrop); | ||
off(this.ownerDocument, 'mouseup', this._onDrop); | ||
}, | ||
_unbindDragEvents: function _unbindDragEvents() { | ||
if (this.nativeDraggable) { | ||
off(this.rootEl, 'dragstart', this._onDragStart); | ||
off(this.rootEl, 'dragover', this._onDragOver); | ||
off(this.rootEl, 'dragend', this._onDrop); | ||
} | ||
} | ||
@@ -725,40 +822,40 @@ }; | ||
autoScroll: true, | ||
// 拖拽到容器边缘时自动滚动 | ||
// Auto scrolling when dragging to the edge of the container | ||
scrollStep: 5, | ||
// 每一帧滚动的距离 | ||
// The distance to scroll each frame | ||
scrollThreshold: 15, | ||
// 自动滚动的阈值 | ||
// Autoscroll threshold | ||
delay: 0, | ||
// 定义鼠标选中列表单元可以开始拖动的延迟时间 | ||
// Defines the delay time after which the mouse-selected list cell can start dragging | ||
delayOnTouchOnly: false, | ||
// only delay if user is using touch | ||
disabled: false, | ||
// 定义是否此sortable对象是否可用,为true时sortable对象不能拖放排序等功能,为false时为可以进行排序,相当于一个开关 | ||
// Defines whether the sortable object is available or not. When it is true, the sortable object cannot drag and drop sorting and other functions. When it is false, it can be sorted, which is equivalent to a switch. | ||
animation: 150, | ||
// 定义排序动画的时间 | ||
// Define the timing of the sorting animation | ||
ghostAnimation: 0, | ||
// 拖拽元素销毁时动画效果 | ||
// Animation when the ghost element is destroyed | ||
ghostClass: '', | ||
// 拖拽元素Class类名 | ||
// Ghost element class name | ||
ghostStyle: {}, | ||
// 拖拽元素样式 | ||
// Ghost element style | ||
chosenClass: '', | ||
// 选中元素样式 | ||
// Chosen element style | ||
draggable: undefined, | ||
// String: css选择器, Function: (e) => return true | ||
// String: css selector, Function: (e) => return true | ||
dragging: undefined, | ||
// 设置拖拽元素,必须为函数且必须返回一个 HTMLElement: (e) => return e.target | ||
// Set the drag element, must be a function and must return an HTMLElement: (e) => return e.target | ||
onDrag: undefined, | ||
// 拖拽开始时触发的回调函数: () => {} | ||
// The callback function triggered when dragging starts: () => {} | ||
onMove: undefined, | ||
// 拖拽过程中的回调函数: (from, to) => {} | ||
// The callback function during drag and drop: (from, to) => {} | ||
onDrop: undefined, | ||
// 拖拽完成时的回调函数: (from, to, changed) => {} | ||
// The callback function when the drag is completed: (from, to, changed) => {} | ||
onChange: undefined, | ||
// 拖拽元素改变位置的时候: (from, to) => {} | ||
// The callback function when dragging an element to change its position: (from, to) => {} | ||
fallbackOnBody: false, | ||
forceFallback: false, | ||
// 忽略 HTML5拖拽行为,强制回调进行 | ||
// Ignore HTML5 drag and drop behavior, force callback to proceed | ||
stopPropagation: false, | ||
// 阻止捕获和冒泡阶段中当前事件的进一步传播 | ||
// Prevents further propagation of the current event in the capture and bubbling phases | ||
supportPointer: 'PointerEvent' in window && !Safari, | ||
@@ -778,11 +875,11 @@ supportTouch: 'ontouchstart' in window | ||
}; | ||
this.state = new State(); // 拖拽过程中状态记录 | ||
this.state = new State(); // Status record during drag and drop | ||
this.differ = new Differ(); // 记录拖拽前后差异 | ||
this.differ = new Differ(); // Record the difference before and after dragging | ||
this.ghost = new Ghost(this); // 拖拽时蒙版元素 | ||
this.ghost = new Ghost(this); // Mask element while dragging | ||
this.dragEl = null; // 拖拽元素 | ||
this.dragEl = null; // Drag element | ||
this.dropEl = null; // 释放元素 | ||
this.dropEl = null; // Drop element | ||
@@ -792,14 +889,5 @@ this.dragStartTimer = null; // setTimeout timer | ||
this.autoScrollTimer = null; | ||
Object.assign(this, Animation(), DNDEvent()); | ||
this._onStart = this._onStart.bind(this); | ||
this._onMove = this._onMove.bind(this); | ||
this._onDrop = this._onDrop.bind(this); | ||
Object.assign(this, Animation(), AutoScroll(), DNDEvent()); | ||
this._bindEventListener(); | ||
if (!window.requestAnimationFrame) { | ||
window.requestAnimationFrame = function (callback) { | ||
return setTimeout(callback, 17); | ||
}; | ||
} | ||
this._bindDragEventListener(); | ||
} | ||
@@ -814,5 +902,10 @@ | ||
destroy: function destroy() { | ||
this._unbindEventListener(); | ||
this._clearState(); | ||
this._clearState(); | ||
this._unbindDragEventListener(); // Remove draggable attributes | ||
Array.prototype.forEach.call(this.rootEl.querySelectorAll('[draggable]'), function (el) { | ||
el.removeAttribute('draggable'); | ||
}); | ||
}, | ||
@@ -834,3 +927,3 @@ | ||
// -------------------------------- prepare start ---------------------------------- | ||
_onStart: function _onStart( | ||
_onDrag: function _onDrag( | ||
/** Event|TouchEvent */ | ||
@@ -849,22 +942,5 @@ evt) { | ||
var _this$options = this.options, | ||
delay = _this$options.delay, | ||
delayOnTouchOnly = _this$options.delayOnTouchOnly; | ||
draggable = _this$options.draggable, | ||
dragging = _this$options.dragging; | ||
if (delay && (!delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { | ||
clearTimeout(this.dragStartTimer); // delay to start | ||
this.dragStartTimer = setTimeout(function () { | ||
return _this2._onDrag(e, touch); | ||
}, delay); | ||
} else { | ||
this._onDrag(e, touch); | ||
} | ||
}, | ||
_onDrag: function _onDrag( | ||
/** Event|TouchEvent */ | ||
e, touch) { | ||
var _this$options2 = this.options, | ||
draggable = _this$options2.draggable, | ||
dragging = _this$options2.dragging; | ||
if (typeof draggable === 'function') { | ||
@@ -876,7 +952,5 @@ if (!draggable(e)) return true; | ||
throw new Error("draggable expected \"function\" or \"string\" but received \"".concat(_typeof(draggable), "\"")); | ||
} | ||
} // Get the dragged element | ||
this._removeSelection(); // 获取拖拽元素 | ||
if (dragging) { | ||
@@ -886,6 +960,6 @@ if (typeof dragging === 'function') this.dragEl = dragging(e);else throw new Error("dragging expected \"function\" or \"string\" but received \"".concat(_typeof(dragging), "\"")); | ||
this.dragEl = getElement(this.rootEl, e.target, true); | ||
} // 不存在拖拽元素时不允许拖拽 | ||
} // No dragging is allowed when there is no dragging element | ||
if (!this.dragEl || this.dragEl.animated) return true; // 获取拖拽元素在列表中的位置 | ||
if (!this.dragEl || this.dragEl.animated) return true; // get the position of the dragged element in the list | ||
@@ -910,26 +984,79 @@ var _getElement = getElement(this.rootEl, this.dragEl), | ||
this.state.sortableDown = e; // sortable state down is active | ||
// Solve the problem that `dragend` does not take effect when the `dragover` event is not triggered | ||
this._bindMoveEvents(touch); | ||
on(this.ownerDocument, 'pointerup', this._onDrop); | ||
on(this.ownerDocument, 'touchend', this._onDrop); | ||
on(this.ownerDocument, 'mouseup', this._onDrop); | ||
var _this$options2 = this.options, | ||
delay = _this$options2.delay, | ||
delayOnTouchOnly = _this$options2.delayOnTouchOnly; | ||
this._bindUpEvents(touch); | ||
if (delay && (!delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { | ||
clearTimeout(this.dragStartTimer); // delay to start | ||
this.dragStartTimer = setTimeout(function () { | ||
return _this2._onStart(e, touch); | ||
}, delay); | ||
} else { | ||
this._onStart(e, touch); | ||
} | ||
}, | ||
// -------------------------------- is started ---------------------------------- | ||
_onStarted: function _onStarted(e, | ||
/** originalEvent */ | ||
evt) { | ||
if (!this.ghost.$el) { | ||
// 将初始化放到move事件中,防止与click事件冲突 | ||
var rect = this.differ.from.rect; | ||
this.ghost.init(this.dragEl.cloneNode(true), rect); // add class for drag element | ||
_onStart: function _onStart( | ||
/** Event|TouchEvent */ | ||
e, touch) { | ||
if (!this.nativeDraggable || touch) { | ||
this._bindMoveEvents(touch); | ||
toggleClass(this.dragEl, this.options.chosenClass, true); // 解决移动端无法拖拽问题 | ||
on(this.ownerDocument, 'pointercancel', this._onDrop); | ||
on(this.ownerDocument, 'touchcancel', this._onDrop); | ||
} else { | ||
this.dragEl.draggable = true; | ||
this._onDragStart = this._onDragStart.bind(this); | ||
this._onDragOver = this._onDragOver.bind(this); | ||
on(this.rootEl, 'dragstart', this._onDragStart); | ||
} // clear selection | ||
this.dragEl.style['touch-action'] = 'none'; | ||
this.dragEl.style['will-change'] = 'transform'; // onDrag callback | ||
var onDrag = this.options.onDrag; | ||
if (onDrag && typeof onDrag === 'function') onDrag(this.dragEl, e, evt); | ||
if (Safari) css(document.body, 'user-select', 'none'); | ||
try { | ||
if (document.selection) { | ||
// Timeout neccessary for IE9 | ||
_nextTick(function () { | ||
document.selection.empty(); | ||
}); | ||
} else { | ||
window.getSelection().removeAllRanges(); | ||
} | ||
} catch (error) {// | ||
} | ||
}, | ||
// -------------------------------- drag event ---------------------------------- | ||
_onDragStart: function _onDragStart(evt) { | ||
// elements can only be dragged after firefox sets setData | ||
evt.dataTransfer.setData('te', evt.target.innerText); | ||
on(this.rootEl, 'dragover', this._onDragOver); | ||
on(this.rootEl, 'dragend', this._onDrop); | ||
}, | ||
_onDragOver: function _onDragOver(evt) { | ||
if (!this.state.sortableDown) return; | ||
var stopPropagation = this.options.stopPropagation; | ||
stopPropagation && evt.stopPropagation && evt.stopPropagation(); // prevent events from bubbling | ||
evt.preventDefault !== void 0 && evt.cancelable && evt.preventDefault(); // prevent scrolling | ||
var clientX = evt.clientX, | ||
clientY = evt.clientY; | ||
var distanceX = clientX - this.move.x; | ||
var distanceY = clientY - this.move.y; | ||
if (clientX !== void 0 && Math.abs(distanceX) <= 0 && clientY !== void 0 && Math.abs(distanceY) <= 0) { | ||
return; | ||
} // truly started | ||
this._onStarted(evt, evt); | ||
if (evt.target === this.rootEl) return; | ||
this._onChange(this, evt.target, evt, evt); | ||
}, | ||
// -------------------------------- on move ---------------------------------- | ||
@@ -954,6 +1081,4 @@ _onMove: function _onMove( | ||
this.state.sortableMove = e; // sortable state move is active | ||
var stopPropagation = this.options.stopPropagation; | ||
stopPropagation && evt.stopPropagation && evt.stopPropagation(); // 阻止事件冒泡 | ||
stopPropagation && evt.stopPropagation && evt.stopPropagation(); // prevent events from bubbling | ||
@@ -964,6 +1089,6 @@ evt.preventDefault !== void 0 && evt.cancelable && evt.preventDefault(); // prevent scrolling | ||
this.ghost.move(distanceX, distanceY); // 拖拽过程中触发的回调 | ||
this.ghost.move(distanceX, distanceY); // onMove callback | ||
var onMove = this.options.onMove; | ||
if (onMove && typeof onMove === 'function') onMove(this.differ.from, this.ghost.$el, e, evt); // 判断边界值 | ||
if (onMove && typeof onMove === 'function') onMove(this.differ.from, this.ghost.$el, e, evt); // boundary value judgment | ||
@@ -991,2 +1116,24 @@ if (clientX < 0 || clientY < 0) return; | ||
}, | ||
_onStarted: function _onStarted(e, | ||
/** originalEvent */ | ||
evt) { | ||
this.state.sortableMove = e; // sortable state move is active | ||
if (!this.ghost.$el) { | ||
// Init in the move event to prevent conflict with the click event | ||
var rect = this.differ.from.rect; | ||
var ghostEl = this.dragEl.cloneNode(true); | ||
this.ghost.init(ghostEl, rect, !this.nativeDraggable); // add class for drag element | ||
toggleClass(this.dragEl, this.options.chosenClass, true); // solve the problem that the mobile cannot be dragged | ||
this.dragEl.style['touch-action'] = 'none'; | ||
this.dragEl.style['will-change'] = 'transform'; // onDrag callback | ||
var onDrag = this.options.onDrag; | ||
if (onDrag && typeof onDrag === 'function') onDrag(this.dragEl, e, evt); | ||
if (Safari) css(document.body, 'user-select', 'none'); | ||
if (this.nativeDraggable) this._unbindDropEvents(); | ||
} | ||
}, | ||
_onChange: debounce(function (_this, target, e, evt) { | ||
@@ -1008,3 +1155,3 @@ var _getElement2 = getElement(_this.rootEl, target), | ||
if (clientX > left && clientX < right && clientY > top && clientY < bottom) { | ||
// 拖拽前后元素不一致时交换 | ||
// swap when the elements before and after the drag are inconsistent | ||
if (el !== _this.dragEl) { | ||
@@ -1021,7 +1168,6 @@ _this.differ.to = { | ||
var _offset = getOffset(_this.dragEl); // 获取拖拽元素的 offset 值 | ||
// 元素发生位置交换时触发的回调 | ||
var _offset = getOffset(_this.dragEl); // onChange callback | ||
if (onChange && typeof onChange === 'function') onChange(_this.differ.from, _this.differ.to, e, evt); // 优先比较 top 值,top 值相同再比较 left | ||
if (onChange && typeof onChange === 'function') onChange(_this.differ.from, _this.differ.to, e, evt); // the top value is compared first, and the left is compared if the top value is the same | ||
@@ -1042,18 +1188,20 @@ if (_offset.top < offset.top || _offset.left < offset.left) { | ||
evt) { | ||
this._unbindDragEvents(); | ||
this._unbindMoveEvents(); | ||
this._unbindUpEvents(); | ||
this._unbindDropEvents(); | ||
clearTimeout(this.dragStartTimer); | ||
this.dragStartTimer && clearTimeout(this.dragStartTimer); | ||
var stopPropagation = this.options.stopPropagation; | ||
stopPropagation && evt.stopPropagation(); // 阻止事件冒泡 | ||
stopPropagation && evt.stopPropagation(); | ||
evt.preventDefault && evt.preventDefault(); // clear style and class | ||
evt.cancelable && evt.preventDefault(); // clear style and class | ||
toggleClass(this.dragEl, this.options.chosenClass, false); | ||
this.dragEl.style['touch-action'] = ''; | ||
this.dragEl.style['will-change'] = ''; | ||
this.dragEl.draggable = false; | ||
if (this.state.sortableDown && this.state.sortableMove) { | ||
// 重新获取一次拖拽元素的 offset 和 rect 值作为拖拽完成后的值 | ||
// re-acquire the offset and rect values of the dragged element as the value after the drag is completed | ||
this.differ.to.offset = getOffset(this.dragEl); | ||
@@ -1063,3 +1211,3 @@ this.differ.to.rect = getRect(this.dragEl); | ||
from = _this$differ.from, | ||
to = _this$differ.to; // 通过 offset 比较是否进行了元素交换 | ||
to = _this$differ.to; // compare whether the element is swapped by offset | ||
@@ -1070,107 +1218,10 @@ var changed = from.offset.top !== to.offset.top || from.offset.left !== to.offset.left; // onDrop callback | ||
if (onDrop && typeof onDrop === 'function') onDrop(changed, evt); | ||
this.ghost.destroy(to.rect); | ||
} | ||
this.differ.destroy(); | ||
this.state = new State(); | ||
this._clearState(); | ||
this.ghost.destroy(this.differ.to.rect); | ||
if (Safari) css(document.body, 'user-select', ''); | ||
}, | ||
// -------------------------------- auto scroll ---------------------------------- | ||
_autoScroll: throttle(function (_this) { | ||
// check if is moving now | ||
if (!(_this.state.sortableDown && _this.state.sortableMove)) return; | ||
var _this$state$sortableM = _this.state.sortableMove, | ||
clientX = _this$state$sortableM.clientX, | ||
clientY = _this$state$sortableM.clientY; | ||
if (clientX === void 0 || clientY === void 0) return; | ||
if (_this.scrollEl === _this.ownerDocument) ; else { | ||
var _this$scrollEl = _this.scrollEl, | ||
scrollTop = _this$scrollEl.scrollTop, | ||
scrollLeft = _this$scrollEl.scrollLeft, | ||
scrollHeight = _this$scrollEl.scrollHeight, | ||
scrollWidth = _this$scrollEl.scrollWidth; | ||
var _getRect2 = getRect(_this.scrollEl), | ||
top = _getRect2.top, | ||
right = _getRect2.right, | ||
bottom = _getRect2.bottom, | ||
left = _getRect2.left, | ||
height = _getRect2.height, | ||
width = _getRect2.width; | ||
var _this$options3 = _this.options, | ||
scrollStep = _this$options3.scrollStep, | ||
scrollThreshold = _this$options3.scrollThreshold; // check direction | ||
var totop = scrollTop > 0 && clientY >= top && clientY <= top + scrollThreshold; | ||
var toleft = scrollLeft > 0 && clientX >= left && clientX <= left + scrollThreshold; | ||
var toright = scrollLeft + width < scrollWidth && clientX <= right && clientX >= right - scrollThreshold; | ||
var tobottom = scrollTop + height < scrollHeight && clientY <= bottom && clientY >= bottom - scrollThreshold; // scroll position | ||
var position = { | ||
x: scrollLeft, | ||
y: scrollTop | ||
}; | ||
if (totop) { | ||
if (toleft) { | ||
// to top-left | ||
position.x = scrollLeft - scrollStep; | ||
} else if (toright) { | ||
// to top-right | ||
position.x = scrollLeft + scrollStep; | ||
} else { | ||
// to top | ||
position.x = scrollLeft; | ||
} | ||
position.y = scrollTop - scrollStep; | ||
} else if (tobottom) { | ||
if (toleft) { | ||
// to bottom-left | ||
position.x = scrollLeft - scrollStep; | ||
} else if (toright) { | ||
// to bottom-right | ||
position.x = scrollLeft + scrollStep; | ||
} else { | ||
// to bottom | ||
position.x = scrollLeft; | ||
} | ||
position.y = scrollTop + scrollStep; | ||
} else if (toleft) { | ||
// to left | ||
position.x = scrollLeft - scrollStep; | ||
position.y = scrollTop; | ||
} else if (toright) { | ||
// to right | ||
position.x = scrollLeft + scrollStep; | ||
position.y = scrollTop; | ||
} // if need to scroll | ||
if (totop || toleft || toright || tobottom) { | ||
requestAnimationFrame(function () { | ||
_this.scrollEl.scrollTo(position.x, position.y); | ||
_this._autoScroll(_this); | ||
}); | ||
} | ||
} | ||
}, 10), | ||
// -------------------------------- clear ---------------------------------- | ||
_removeSelection: function _removeSelection() { | ||
try { | ||
if (document.selection) { | ||
// Timeout neccessary for IE9 | ||
_nextTick(function () { | ||
document.selection.empty(); | ||
}); | ||
} else { | ||
window.getSelection().removeAllRanges(); | ||
} | ||
} catch (error) {// | ||
} | ||
}, | ||
_clearState: function _clearState() { | ||
@@ -1180,7 +1231,6 @@ this.dragEl = null; | ||
this.state = new State(); | ||
this.ghost.destroy(); | ||
this.differ.destroy(); | ||
} | ||
}; | ||
Sortable.utils = { | ||
Sortable.prototype.utils = { | ||
getRect: getRect, | ||
@@ -1187,0 +1237,0 @@ getOffset: getOffset, |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Sortable=e()}(this,function(){"use strict";function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var o=0;o<e.length;o++){var n=e[o];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}function r(t,e,o){return e&&n(t.prototype,e),o&&n(t,o),Object.defineProperty(t,"prototype",{writable:!1}),t}function s(t){return function(t){if(Array.isArray(t))return a(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return a(t,e);var o=Object.prototype.toString.call(t).slice(8,-1);return"Map"===(o="Object"===o&&t.constructor?t.constructor.name:o)||"Set"===o?Array.from(t):"Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?a(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(t,e){(null==e||e>t.length)&&(e=t.length);for(var o=0,n=new Array(e);o<e;o++)n[o]=t[o];return n}function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var e,l=t(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),c=t(/Edge/i),h=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),u=t(/iP(ad|od|hone)/i),f=t(/chrome/i)&&t(/android/i),d={capture:!1,passive:!1},p=/\s+/g,m=["-webkit-transition","-moz-transition","-ms-transition","-o-transition","transition"],g=["-webkit-transform","-moz-transform","-ms-transform","-o-transform","transform"],v=(e=!1,document.addEventListener("checkIfSupportPassive",null,{get passive(){return e=!0}}),e);function y(e,o){o?"none"===o?m.forEach(function(t){return M(e,t,"none")}):m.forEach(function(t){return M(e,t,"".concat(t.split("transition")[0],"transform ").concat(o))}):m.forEach(function(t){return M(e,t,"")})}function w(e,o){o?g.forEach(function(t){return M(e,t,"".concat(t.split("transform")[0]).concat(o))}):g.forEach(function(t){return M(e,t,"")})}function b(t,e,o){window.addEventListener?t.addEventListener(e,o,!(!v&&l)&&d):window.attachEvent&&t.attachEvent("on"+e,o)}function E(t,e,o){window.removeEventListener?t.removeEventListener(e,o,!(!v&&l)&&d):window.detachEvent&&t.detachEvent("on"+e,o)}function S(t){for(var e={top:0,left:0,height:0,width:0},o=(e.height=t.offsetHeight,e.width=t.offsetWidth,e.top=t.offsetTop,e.left=t.offsetLeft,t.offsetParent);null!==o;)e.top+=o.offsetTop,e.left+=o.offsetLeft,o=o.offsetParent;return e}function _(t,e){if(!t||!t.getBoundingClientRect)return D();var o=t,n=!1;do{if(o.clientWidth<o.scrollWidth||o.clientHeight<o.scrollHeight){var i=M(o);if(o.clientWidth<o.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||o.clientHeight<o.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!o.getBoundingClientRect||o===document.body)return D();if(n||e)return o;n=!0}}}while(o=o.parentNode);return D()}function D(){var t=document.scrollingElement;return!t||t.contains(document.body)?document:t}function T(t){var e;if(t.getBoundingClientRect||t===window)return e={top:0,left:0,bottom:0,right:0,height:0,width:0},t!==window&&t.parentNode&&t!==D()?(t=t.getBoundingClientRect(),e.top=t.top,e.left=t.left,e.bottom=t.bottom,e.right=t.right,e.height=t.height,e.width=t.width):(e.top=0,e.left=0,e.bottom=window.innerHeight,e.right=window.innerWidth,e.height=window.innerHeight,e.width=window.innerWidth),e}function x(t,e,o){var n=s(Array.from(t.children)),t=n.indexOf(e);if(-1<t)return o?n[t]:{index:t,el:n[t],rect:T(n[t]),offset:S(n[t])};for(var i=0;i<n.length;i++)if(function(t,e){var o;if(t&&e)for(o=t.parentNode;o;){if(e===o)return 1;o=o.parentNode}return}(e,n[i]))return o?n[i]:{index:i,el:n[i],rect:T(n[i]),offset:S(n[i])};return o?null:{index:-1,el:null,rect:{},offset:{}}}function $(t,e,o){var n;t&&e&&(t.classList?t.classList[o?"add":"remove"](e):(n=(" "+t.className+" ").replace(p," ").replace(" "+e+" "," "),t.className=(n+(o?" "+e:"")).replace(p," ")))}function M(t,e,o){var n=t&&t.style;if(n){if(void 0===o)return document.defaultView&&document.defaultView.getComputedStyle?o=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(o=t.currentStyle),void 0===e?o:o[e];n[e=e in n||-1!==e.indexOf("webkit")?e:"-webkit-"+e]=o+("string"==typeof o?"":"px")}}function k(o,n,i){var r=null;return function(){var t=this,e=arguments;r&&clearTimeout(r),i&&!r&&o.apply(t,e),r=setTimeout(function(){o.apply(t,e)},n)}}function P(o,n){var i=null;return function(){var t=this,e=arguments;i=i||setTimeout(function(){i=null,o.apply(t,e)},n)}}var A=r(function t(){o(this,t),this.sortableDown=void 0,this.sortableMove=void 0,this.animationEnd=void 0}),C=function(){function t(){o(this,t),this.from={node:null,rect:{},offset:{}},this.to={node:null,rect:{},offset:{}}}return r(t,[{key:"get",value:function(t){return this[t]}},{key:"set",value:function(t,e){this[t]=e}},{key:"destroy",value:function(){this.from={node:null,rect:{},offset:{}},this.to={node:null,rect:{},offset:{}}}}]),t}(),L=function(){function e(t){o(this,e),this.$el=null,this.distance={x:0,y:0},this.options=t.options,this.container=t.container}return r(e,[{key:"init",value:function(t,e){this.$el=t;var t=this.options,o=t.ghostClass,t=t.ghostStyle,t=void 0===t?{}:t;$(this.$el,o,!0),M(this.$el,"box-sizing","border-box"),M(this.$el,"margin",0),M(this.$el,"top",e.top),M(this.$el,"left",e.left),M(this.$el,"width",e.width),M(this.$el,"height",e.height),M(this.$el,"opacity","0.8"),M(this.$el,"position","fixed"),M(this.$el,"zIndex","100000"),M(this.$el,"pointerEvents","none"),this.setStyle(t),y(this.$el,"none"),w(this.$el,"translate3d(0px, 0px, 0px)"),this.container.appendChild(this.$el),M(this.$el,"transform-origin",this.distance.x/parseInt(this.$el.style.width)*100+"% "+this.distance.y/parseInt(this.$el.style.height)*100+"%")}},{key:"setStyle",value:function(t){for(var e in t)M(this.$el,e,t[e])}},{key:"rect",value:function(){return T(this.$el)}},{key:"move",value:function(t,e){this.$el&&(y(this.$el,2<arguments.length&&void 0!==arguments[2]&&arguments[2]?"".concat(this.options.ghostAnimation,"ms"):"none"),w(this.$el,"translate3d(".concat(t,"px, ").concat(e,"px, 0)")))}},{key:"destroy",value:function(t){var e,o,n=this;this.$el&&(o=parseInt(this.$el.style.left),e=parseInt(this.$el.style.top),this.move(t.left-o,t.top-e,!0),(o=this.options.ghostAnimation)?setTimeout(function(){return n.clear()},o):this.clear())}},{key:"clear",value:function(){this.$el&&this.$el.remove(),this.distance={x:0,y:0},this.$el=null}}]),e}();function O(){var i=[];return{captureAnimationState:function(){var t=s(Array.from(this.rootEl.children)),e=(o=t,n=this.dragEl,e=this.dropEl,n=o.indexOf(n),o=o.indexOf(e),n<o?{start:n,end:o}:{start:o,end:n}),o=e.start,n=e.end;i.length=0,t.slice(o,n+1).forEach(function(t){i.push({target:t,rect:T(t)})})},animateRange:function(){var o=this;i.forEach(function(t){var e=t.target,t=t.rect;o.animate(e,t,o.options.animation)})},animate:function(t,e){var o=2<arguments.length&&void 0!==arguments[2]?arguments[2]:150,n=T(t),i=e.left-n.left,e=e.top-n.top;y(t,"none"),w(t,"translate3d(".concat(i,"px, ").concat(e,"px, 0)")),t.offsetLeft,y(t,"".concat(o,"ms")),w(t,"translate3d(0px, 0px, 0px)"),clearTimeout(t.animated),t.animated=setTimeout(function(){y(t,""),w(t,""),t.animated=null},o)}}}var I="undefined"!=typeof document&&!f&&!u&&"draggable"in document.createElement("div");function H(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.rootEl=t,this.scrollEl=_(t,!0),this.options=e=Object.assign({},e),this.ownerDocument=t.ownerDocument;var o,n={autoScroll:!0,scrollStep:5,scrollThreshold:15,delay:0,delayOnTouchOnly:!1,disabled:!1,animation:150,ghostAnimation:0,ghostClass:"",ghostStyle:{},chosenClass:"",draggable:void 0,dragging:void 0,onDrag:void 0,onMove:void 0,onDrop:void 0,onChange:void 0,fallbackOnBody:!1,forceFallback:!1,stopPropagation:!1,supportPointer:"PointerEvent"in window&&!h,supportTouch:"ontouchstart"in window};for(o in n)o in this.options||(this.options[o]=n[o]);this.container=this.options.fallbackOnBody?document.body:this.rootEl,this.nativeDraggable=!this.options.forceFallback&&I,this.move={x:0,y:0},this.state=new A,this.differ=new C,this.ghost=new L(this),this.dragEl=null,this.dropEl=null,this.dragStartTimer=null,this.autoScrollTimer=null,Object.assign(this,O(),{_bindEventListener:function(){var t=this.options,e=t.supportPointer,t=t.supportTouch;b(this.rootEl,e?"pointerdown":t?"touchstart":"mousedown",this._onStart)},_unbindEventListener:function(){E(this.rootEl,"pointerdown",this._onStart),E(this.rootEl,"touchstart",this._onStart),E(this.rootEl,"mousedown",this._onStart)},_bindMoveEvents:function(t){this.options.supportPointer?b(this.ownerDocument,"pointermove",this._onMove):b(this.ownerDocument,t?"touchmove":"mousemove",this._onMove)},_bindUpEvents:function(){b(this.ownerDocument,"pointerup",this._onDrop),b(this.ownerDocument,"pointercancel",this._onDrop),b(this.ownerDocument,"touchend",this._onDrop),b(this.ownerDocument,"touchcancel",this._onDrop),b(this.ownerDocument,"mouseup",this._onDrop)},_unbindMoveEvents:function(){E(this.ownerDocument,"pointermove",this._onMove),E(this.ownerDocument,"touchmove",this._onMove),E(this.ownerDocument,"mousemove",this._onMove)},_unbindUpEvents:function(){E(this.ownerDocument,"pointerup",this._onDrop),E(this.ownerDocument,"pointercancel",this._onDrop),E(this.ownerDocument,"touchend",this._onDrop),E(this.ownerDocument,"touchcancel",this._onDrop),E(this.ownerDocument,"mouseup",this._onDrop)}}),this._onStart=this._onStart.bind(this),this._onMove=this._onMove.bind(this),this._onDrop=this._onDrop.bind(this),this._bindEventListener(),window.requestAnimationFrame||(window.requestAnimationFrame=function(t){return setTimeout(t,17)})}return H.prototype={constructor:H,destroy:function(){this._unbindEventListener(),this._clearState()},set:function(t,e){this.options[t]=e},get:function(t){return this.options[t]},_onStart:function(t){var e=this;if(!(/mousedown|pointerdown/.test(t.type)&&0!==t.button||this.options.disabled)){var o=t.touches&&t.touches[0]||t.pointerType&&"touch"===t.pointerType&&t,n=o||t;if(this.nativeDraggable||!h||!n.target||"SELECT"!==n.target.tagName.toUpperCase()){if(n.target===this.rootEl)return!0;this.options.stopPropagation&&t.stopPropagation();var t=this.options,i=t.delay,t=t.delayOnTouchOnly;!i||t&&!o||this.nativeDraggable&&(c||l)?this._onDrag(n,o):(clearTimeout(this.dragStartTimer),this.dragStartTimer=setTimeout(function(){return e._onDrag(n,o)},i))}}},_onDrag:function(t,e){var o=this.options,n=o.draggable,o=o.dragging;if("function"==typeof n){if(!n(t))return!0}else if("string"==typeof n){if(!function(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}(t.target,n))return!0}else if(void 0!==n)throw new Error('draggable expected "function" or "string" but received "'.concat(i(n),'"'));if(this._removeSelection(),o){if("function"!=typeof o)throw new Error('dragging expected "function" or "string" but received "'.concat(i(o),'"'));this.dragEl=o(t)}else this.dragEl=x(this.rootEl,t.target,!0);if(!this.dragEl||this.dragEl.animated)return!0;n=x(this.rootEl,this.dragEl),o=n.rect,n=n.offset;this.move={x:t.clientX,y:t.clientY},this.differ.from={node:this.dragEl,rect:o,offset:n},this.ghost.distance={x:t.clientX-o.left,y:t.clientY-o.top},this.state.sortableDown=t,this._bindMoveEvents(e),this._bindUpEvents(e)},_onStarted:function(t,e){var o;this.ghost.$el||(o=this.differ.from.rect,this.ghost.init(this.dragEl.cloneNode(!0),o),$(this.dragEl,this.options.chosenClass,!0),this.dragEl.style["touch-action"]="none",this.dragEl.style["will-change"]="transform",(o=this.options.onDrag)&&"function"==typeof o&&o(this.dragEl,t,e),h&&M(document.body,"user-select","none"))},_onMove:function(t){var e,o,n,i,r,s,a,l,c=this;this.state.sortableDown&&(o=(e=(i=t.touches&&t.touches[0]||t.pointerType&&"touch"===t.pointerType&&t)||t).clientX,n=e.clientY,i=i?document.elementFromPoint(o,n):e.target,s=o-this.move.x,r=n-this.move.y,void 0!==o&&Math.abs(s)<=0&&void 0!==n&&Math.abs(r)<=0||(this.state.sortableMove=e,this.options.stopPropagation&&t.stopPropagation&&t.stopPropagation(),void 0!==t.preventDefault&&t.cancelable&&t.preventDefault(),this._onStarted(e,t),this.ghost.move(s,r),(s=this.options.onMove)&&"function"==typeof s&&s(this.differ.from,this.ghost.$el,e,t),o<0||n<0||(s=(r=T(this.rootEl)).top,a=r.right,l=r.bottom,o<r.left||a<o||n<s||l<n||(this._onChange(this,i,e,t),this.autoScrollTimer&&clearTimeout(this.autoScrollTimer),this.options.autoScroll&&(this.autoScrollTimer=setTimeout(function(){return c._autoScroll(c)},0))))))},_onChange:k(function(t,e,o,n){var i,r,s,a,l,c,e=x(t.rootEl,e),h=e.el,u=e.rect,e=e.offset;h&&!h.animated&&(t.dropEl=h,c=o.clientX,i=o.clientY,l=u.left,r=u.right,s=u.top,a=u.bottom,l<c&&c<r&&s<i&&i<a&&h!==t.dragEl&&(t.differ.to={node:t.dropEl,rect:u,offset:e},t.captureAnimationState(),l=t.options.onChange,c=S(t.dragEl),l&&"function"==typeof l&&l(t.differ.from,t.differ.to,o,n),c.top<e.top||c.left<e.left?t.rootEl.insertBefore(t.dragEl,h.nextElementSibling):t.rootEl.insertBefore(t.dragEl,h),t.animateRange()))},5),_onDrop:function(t){var e,o,n;this._unbindMoveEvents(),this._unbindUpEvents(),clearTimeout(this.dragStartTimer),this.options.stopPropagation&&t.stopPropagation(),t.cancelable&&t.preventDefault(),$(this.dragEl,this.options.chosenClass,!1),this.dragEl.style["touch-action"]="",this.dragEl.style["will-change"]="",this.state.sortableDown&&this.state.sortableMove&&(this.differ.to.offset=S(this.dragEl),this.differ.to.rect=T(this.dragEl),o=(e=this.differ).from,e=e.to,o=o.offset.top!==e.offset.top||o.offset.left!==e.offset.left,(n=this.options.onDrop)&&"function"==typeof n&&n(o,t),this.ghost.destroy(e.rect)),this.differ.destroy(),this.state=new A,h&&M(document.body,"user-select","")},_autoScroll:P(function(t){var e,o,n,i,r,s,a,l,c,h,u,f,d,p,m;t.state.sortableDown&&t.state.sortableMove&&(e=(o=t.state.sortableMove).clientX,o=o.clientY,void 0!==e&&void 0!==o&&t.scrollEl!==t.ownerDocument&&(n=(p=t.scrollEl).scrollTop,i=p.scrollLeft,r=p.scrollHeight,p=p.scrollWidth,s=(d=T(t.scrollEl)).top,u=d.right,a=d.bottom,f=d.left,l=d.height,d=d.width,c=(h=t.options).scrollStep,h=h.scrollThreshold,f=0<i&&f<=e&&e<=f+h,d=i+d<p&&e<=u&&u-h<=e,p=n+l<r&&o<=a&&a-h<=o,m={x:i,y:n},(u=0<n&&s<=o&&o<=s+h)?(m.x=f?i-c:d?i+c:i,m.y=n-c):p?(m.x=f?i-c:d?i+c:i,m.y=n+c):f?(m.x=i-c,m.y=n):d&&(m.x=i+c,m.y=n),(u||f||d||p)&&requestAnimationFrame(function(){t.scrollEl.scrollTo(m.x,m.y),t._autoScroll(t)})))},10),_removeSelection:function(){try{document.selection?setTimeout(function(){document.selection.empty()},0):window.getSelection().removeAllRanges()}catch(t){}},_clearState:function(){this.dragEl=null,this.dropEl=null,this.state=new A,this.ghost.destroy(),this.differ.destroy()}},H.utils={getRect:T,getOffset:S,debounce:k,throttle:P,getParentAutoScrollElement:_},H}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Sortable=e()}(this,function(){"use strict";function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var o=0;o<e.length;o++){var n=e[o];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}function i(t,e,o){return e&&n(t.prototype,e),o&&n(t,o),Object.defineProperty(t,"prototype",{writable:!1}),t}function s(t){return function(t){if(Array.isArray(t))return a(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return a(t,e);var o=Object.prototype.toString.call(t).slice(8,-1);return"Map"===(o="Object"===o&&t.constructor?t.constructor.name:o)||"Set"===o?Array.from(t):"Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?a(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(t,e){(null==e||e>t.length)&&(e=t.length);for(var o=0,n=new Array(e);o<e;o++)n[o]=t[o];return n}function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var e,l=t(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),h=t(/Edge/i),c=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),u=t(/iP(ad|od|hone)/i),f=t(/chrome/i)&&t(/android/i),d={capture:!1,passive:!1},p=/\s+/g,g=["-webkit-transition","-moz-transition","-ms-transition","-o-transition","transition"],m=["-webkit-transform","-moz-transform","-ms-transform","-o-transform","transform"],v=(e=!1,document.addEventListener("checkIfSupportPassive",null,{get passive(){return e=!0}}),e);function y(e,o){o?"none"===o?g.forEach(function(t){return M(e,t,"none")}):g.forEach(function(t){return M(e,t,"".concat(t.split("transition")[0],"transform ").concat(o))}):g.forEach(function(t){return M(e,t,"")})}function b(e,o){o?m.forEach(function(t){return M(e,t,"".concat(t.split("transform")[0]).concat(o))}):m.forEach(function(t){return M(e,t,"")})}function w(t,e,o){window.addEventListener?t.addEventListener(e,o,!(!v&&l)&&d):window.attachEvent&&t.attachEvent("on"+e,o)}function E(t,e,o){window.removeEventListener?t.removeEventListener(e,o,!(!v&&l)&&d):window.detachEvent&&t.detachEvent("on"+e,o)}function D(t){for(var e={top:0,left:0,height:0,width:0},o=(e.height=t.offsetHeight,e.width=t.offsetWidth,e.top=t.offsetTop,e.left=t.offsetLeft,t.offsetParent);null!==o;)e.top+=o.offsetTop,e.left+=o.offsetLeft,o=o.offsetParent;return e}function _(t,e){if(!t||!t.getBoundingClientRect)return S();var o=t,n=!1;do{if(o.clientWidth<o.scrollWidth||o.clientHeight<o.scrollHeight){var i=M(o);if(o.clientWidth<o.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||o.clientHeight<o.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!o.getBoundingClientRect||o===document.body)return S();if(n||e)return o;n=!0}}}while(o=o.parentNode);return S()}function S(){var t=document.scrollingElement;return!t||t.contains(document.body)?document:t}function T(t){var e;if(t.getBoundingClientRect||t===window)return e={top:0,left:0,bottom:0,right:0,height:0,width:0},t!==window&&t.parentNode&&t!==S()?(t=t.getBoundingClientRect(),e.top=t.top,e.left=t.left,e.bottom=t.bottom,e.right=t.right,e.height=t.height,e.width=t.width):(e.top=0,e.left=0,e.bottom=window.innerHeight,e.right=window.innerWidth,e.height=window.innerHeight,e.width=window.innerWidth),e}function x(t,e,o){var n=s(Array.from(t.children)),t=n.indexOf(e);if(-1<t)return o?n[t]:{index:t,el:n[t],rect:T(n[t]),offset:D(n[t])};for(var i=0;i<n.length;i++)if(function(t,e){var o;if(t&&e)for(o=t.parentNode;o;){if(e===o)return 1;o=o.parentNode}return}(e,n[i]))return o?n[i]:{index:i,el:n[i],rect:T(n[i]),offset:D(n[i])};return o?null:{index:-1,el:null,rect:{},offset:{}}}function $(t,e,o){var n;t&&e&&(t.classList?t.classList[o?"add":"remove"](e):(n=(" "+t.className+" ").replace(p," ").replace(" "+e+" "," "),t.className=(n+(o?" "+e:"")).replace(p," ")))}function M(t,e,o){var n=t&&t.style;if(n){if(void 0===o)return document.defaultView&&document.defaultView.getComputedStyle?o=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(o=t.currentStyle),void 0===e?o:o[e];n[e=e in n||-1!==e.indexOf("webkit")?e:"-webkit-"+e]=o+("string"==typeof o?"":"px")}}function P(o,n,i){var r=null;return function(){var t=this,e=arguments;r&&clearTimeout(r),i&&!r&&o.apply(t,e),r=setTimeout(function(){o.apply(t,e)},n)}}function A(o,n){var i=null;return function(){var t=this,e=arguments;i=i||setTimeout(function(){i=null,o.apply(t,e)},n)}}var O=i(function t(){o(this,t),this.sortableDown=void 0,this.sortableMove=void 0,this.animationEnd=void 0}),k=function(){function t(){o(this,t),this.from={node:null,rect:{},offset:{}},this.to={node:null,rect:{},offset:{}}}return i(t,[{key:"get",value:function(t){return this[t]}},{key:"set",value:function(t,e){this[t]=e}},{key:"destroy",value:function(){this.from={node:null,rect:{},offset:{}},this.to={node:null,rect:{},offset:{}}}}]),t}(),C=function(){function e(t){o(this,e),this.$el=null,this.distance={x:0,y:0},this.options=t.options,this.container=t.container}return i(e,[{key:"init",value:function(t,e){var o=!(2<arguments.length&&void 0!==arguments[2])||arguments[2],t=(this.$el=t,this.options),n=t.ghostClass,t=t.ghostStyle,t=void 0===t?{}:t;$(this.$el,n,!0),M(this.$el,"box-sizing","border-box"),M(this.$el,"margin",0),M(this.$el,"top",e.top),M(this.$el,"left",e.left),M(this.$el,"width",e.width),M(this.$el,"height",e.height),M(this.$el,"opacity","0.8"),M(this.$el,"position","fixed"),M(this.$el,"zIndex","100000"),M(this.$el,"pointerEvents","none"),this.setStyle(t),y(this.$el,"none"),b(this.$el,"translate3d(0px, 0px, 0px)"),o&&this.container.appendChild(this.$el),M(this.$el,"transform-origin",this.distance.x/parseInt(this.$el.style.width)*100+"% "+this.distance.y/parseInt(this.$el.style.height)*100+"%")}},{key:"setStyle",value:function(t){for(var e in t)M(this.$el,e,t[e])}},{key:"rect",value:function(){return T(this.$el)}},{key:"move",value:function(t,e){this.$el&&(y(this.$el,2<arguments.length&&void 0!==arguments[2]&&arguments[2]?"".concat(this.options.ghostAnimation,"ms"):"none"),b(this.$el,"translate3d(".concat(t,"px, ").concat(e,"px, 0)")))}},{key:"destroy",value:function(t){var e,o,n=this;this.$el&&(o=parseInt(this.$el.style.left),e=parseInt(this.$el.style.top),this.move(t.left-o,t.top-e,!0),(o=this.options.ghostAnimation)?setTimeout(function(){return n.clear()},o):this.clear())}},{key:"clear",value:function(){this.$el&&this.$el.remove(),this.distance={x:0,y:0},this.$el=null}}]),e}();function L(){var i=[];return{captureAnimationState:function(){var t=s(Array.from(this.rootEl.children)),e=(o=t,n=this.dragEl,e=this.dropEl,n=o.indexOf(n),o=o.indexOf(e),n<o?{start:n,end:o}:{start:o,end:n}),o=e.start,n=e.end;i.length=0,t.slice(o,n+1).forEach(function(t){i.push({target:t,rect:T(t)})})},animateRange:function(){var o=this;i.forEach(function(t){var e=t.target,t=t.rect;o.animate(e,t,o.options.animation)})},animate:function(t,e){var o=2<arguments.length&&void 0!==arguments[2]?arguments[2]:150,n=T(t),i=e.left-n.left,e=e.top-n.top;y(t,"none"),b(t,"translate3d(".concat(i,"px, ").concat(e,"px, 0)")),t.offsetLeft,y(t,"".concat(o,"ms")),b(t,"translate3d(0px, 0px, 0px)"),clearTimeout(t.animated),t.animated=setTimeout(function(){y(t,""),b(t,""),t.animated=null},o)}}}var I="undefined"!=typeof document&&!f&&!u&&"draggable"in document.createElement("div");function H(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.rootEl=t,this.scrollEl=_(t,!0),this.options=e=Object.assign({},e),this.ownerDocument=t.ownerDocument;var o,n={autoScroll:!0,scrollStep:5,scrollThreshold:15,delay:0,delayOnTouchOnly:!1,disabled:!1,animation:150,ghostAnimation:0,ghostClass:"",ghostStyle:{},chosenClass:"",draggable:void 0,dragging:void 0,onDrag:void 0,onMove:void 0,onDrop:void 0,onChange:void 0,fallbackOnBody:!1,forceFallback:!1,stopPropagation:!1,supportPointer:"PointerEvent"in window&&!c,supportTouch:"ontouchstart"in window};for(o in n)o in this.options||(this.options[o]=n[o]);this.container=this.options.fallbackOnBody?document.body:this.rootEl,this.nativeDraggable=!this.options.forceFallback&&I,this.move={x:0,y:0},this.state=new O,this.differ=new k,this.ghost=new C(this),this.dragEl=null,this.dropEl=null,this.dragStartTimer=null,this.autoScrollTimer=null,Object.assign(this,L(),(window.requestAnimationFrame||(window.requestAnimationFrame=function(t){return setTimeout(t,17)}),{_autoScroll:A(function(t){var e,o,n,i,r,s,a,l,h,c,u,f,d,p,g;t.state.sortableDown&&t.state.sortableMove&&(e=(o=t.state.sortableMove).clientX,o=o.clientY,void 0!==e&&void 0!==o&&t.scrollEl!==t.ownerDocument&&(n=(p=t.scrollEl).scrollTop,i=p.scrollLeft,r=p.scrollHeight,p=p.scrollWidth,s=(d=T(t.scrollEl)).top,u=d.right,a=d.bottom,f=d.left,l=d.height,d=d.width,h=(c=t.options).scrollStep,c=c.scrollThreshold,f=0<i&&f<=e&&e<=f+c,d=i+d<p&&e<=u&&u-c<=e,p=n+l<r&&o<=a&&a-c<=o,g={x:i,y:n},(u=0<n&&s<=o&&o<=s+c)?(g.x=f?i-h:d?i+h:i,g.y=n-h):p?(g.x=f?i-h:d?i+h:i,g.y=n+h):f?(g.x=i-h,g.y=n):d&&(g.x=i+h,g.y=n),(u||f||d||p)&&requestAnimationFrame(function(){t.scrollEl.scrollTo(g.x,g.y),t._autoScroll(t)})))},10)}),{_bindDragEventListener:function(){this._onDrag=this._onDrag.bind(this),this._onMove=this._onMove.bind(this),this._onDrop=this._onDrop.bind(this);var t=this.options,e=t.supportPointer,t=t.supportTouch;w(this.rootEl,e?"pointerdown":t?"touchstart":"mousedown",this._onDrag)},_unbindDragEventListener:function(){E(this.rootEl,"pointerdown",this._onDrag),E(this.rootEl,"touchstart",this._onDrag),E(this.rootEl,"mousedown",this._onDrag)},_bindMoveEvents:function(t){this.options.supportPointer?w(this.ownerDocument,"pointermove",this._onMove):w(this.ownerDocument,t?"touchmove":"mousemove",this._onMove)},_unbindMoveEvents:function(){E(this.ownerDocument,"pointermove",this._onMove),E(this.ownerDocument,"touchmove",this._onMove),E(this.ownerDocument,"mousemove",this._onMove)},_unbindDropEvents:function(){E(this.ownerDocument,"pointerup",this._onDrop),E(this.ownerDocument,"pointercancel",this._onDrop),E(this.ownerDocument,"touchend",this._onDrop),E(this.ownerDocument,"touchcancel",this._onDrop),E(this.ownerDocument,"mouseup",this._onDrop)},_unbindDragEvents:function(){this.nativeDraggable&&(E(this.rootEl,"dragstart",this._onDragStart),E(this.rootEl,"dragover",this._onDragOver),E(this.rootEl,"dragend",this._onDrop))}}),this._bindDragEventListener()}return(H.prototype={constructor:H,destroy:function(){this._clearState(),this._unbindDragEventListener(),Array.prototype.forEach.call(this.rootEl.querySelectorAll("[draggable]"),function(t){t.removeAttribute("draggable")})},set:function(t,e){this.options[t]=e},get:function(t){return this.options[t]},_onDrag:function(t){var e=this;if(!(/mousedown|pointerdown/.test(t.type)&&0!==t.button||this.options.disabled)){var o=t.touches&&t.touches[0]||t.pointerType&&"touch"===t.pointerType&&t,n=o||t;if(this.nativeDraggable||!c||!n.target||"SELECT"!==n.target.tagName.toUpperCase()){if(n.target===this.rootEl)return!0;this.options.stopPropagation&&t.stopPropagation();var t=this.options,i=t.draggable,t=t.dragging;if("function"==typeof i){if(!i(n))return!0}else if("string"==typeof i){if(!function(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}(n.target,i))return!0}else if(void 0!==i)throw new Error('draggable expected "function" or "string" but received "'.concat(r(i),'"'));if(t){if("function"!=typeof t)throw new Error('dragging expected "function" or "string" but received "'.concat(r(t),'"'));this.dragEl=t(n)}else this.dragEl=x(this.rootEl,n.target,!0);if(!this.dragEl||this.dragEl.animated)return!0;i=x(this.rootEl,this.dragEl),t=i.rect,i=i.offset,i=(this.move={x:n.clientX,y:n.clientY},this.differ.from={node:this.dragEl,rect:t,offset:i},this.ghost.distance={x:n.clientX-t.left,y:n.clientY-t.top},this.state.sortableDown=n,w(this.ownerDocument,"pointerup",this._onDrop),w(this.ownerDocument,"touchend",this._onDrop),w(this.ownerDocument,"mouseup",this._onDrop),this.options),t=i.delay,i=i.delayOnTouchOnly;!t||i&&!o||this.nativeDraggable&&(h||l)?this._onStart(n,o):(clearTimeout(this.dragStartTimer),this.dragStartTimer=setTimeout(function(){return e._onStart(n,o)},t))}}},_onStart:function(t,e){!this.nativeDraggable||e?(this._bindMoveEvents(e),w(this.ownerDocument,"pointercancel",this._onDrop),w(this.ownerDocument,"touchcancel",this._onDrop)):(this.dragEl.draggable=!0,this._onDragStart=this._onDragStart.bind(this),this._onDragOver=this._onDragOver.bind(this),w(this.rootEl,"dragstart",this._onDragStart));try{document.selection?setTimeout(function(){document.selection.empty()},0):window.getSelection().removeAllRanges()}catch(t){}},_onDragStart:function(t){t.dataTransfer.setData("te",t.target.innerText),w(this.rootEl,"dragover",this._onDragOver),w(this.rootEl,"dragend",this._onDrop)},_onDragOver:function(t){var e,o,n,i;this.state.sortableDown&&(this.options.stopPropagation&&t.stopPropagation&&t.stopPropagation(),void 0!==t.preventDefault&&t.cancelable&&t.preventDefault(),e=t.clientX,o=t.clientY,n=e-this.move.x,i=o-this.move.y,void 0!==e&&Math.abs(n)<=0&&void 0!==o&&Math.abs(i)<=0||(this._onStarted(t,t),t.target!==this.rootEl&&this._onChange(this,t.target,t,t)))},_onMove:function(t){var e,o,n,i,r,s,a,l,h=this;this.state.sortableDown&&(o=(e=(i=t.touches&&t.touches[0]||t.pointerType&&"touch"===t.pointerType&&t)||t).clientX,n=e.clientY,i=i?document.elementFromPoint(o,n):e.target,s=o-this.move.x,r=n-this.move.y,void 0!==o&&Math.abs(s)<=0&&void 0!==n&&Math.abs(r)<=0||(this.options.stopPropagation&&t.stopPropagation&&t.stopPropagation(),void 0!==t.preventDefault&&t.cancelable&&t.preventDefault(),this._onStarted(e,t),this.ghost.move(s,r),(s=this.options.onMove)&&"function"==typeof s&&s(this.differ.from,this.ghost.$el,e,t),o<0||n<0||(s=(r=T(this.rootEl)).top,a=r.right,l=r.bottom,o<r.left||a<o||n<s||l<n||(this._onChange(this,i,e,t),this.autoScrollTimer&&clearTimeout(this.autoScrollTimer),this.options.autoScroll&&(this.autoScrollTimer=setTimeout(function(){return h._autoScroll(h)},0))))))},_onStarted:function(t,e){var o,n;this.state.sortableMove=t,this.ghost.$el||(o=this.differ.from.rect,n=this.dragEl.cloneNode(!0),this.ghost.init(n,o,!this.nativeDraggable),$(this.dragEl,this.options.chosenClass,!0),this.dragEl.style["touch-action"]="none",this.dragEl.style["will-change"]="transform",(n=this.options.onDrag)&&"function"==typeof n&&n(this.dragEl,t,e),c&&M(document.body,"user-select","none"),this.nativeDraggable&&this._unbindDropEvents())},_onChange:P(function(t,e,o,n){var i,r,s,a,l,h,e=x(t.rootEl,e),c=e.el,u=e.rect,e=e.offset;c&&!c.animated&&(t.dropEl=c,h=o.clientX,i=o.clientY,l=u.left,r=u.right,s=u.top,a=u.bottom,l<h&&h<r&&s<i&&i<a&&c!==t.dragEl&&(t.differ.to={node:t.dropEl,rect:u,offset:e},t.captureAnimationState(),l=t.options.onChange,h=D(t.dragEl),l&&"function"==typeof l&&l(t.differ.from,t.differ.to,o,n),h.top<e.top||h.left<e.left?t.rootEl.insertBefore(t.dragEl,c.nextElementSibling):t.rootEl.insertBefore(t.dragEl,c),t.animateRange()))},5),_onDrop:function(t){var e,o;this._unbindDragEvents(),this._unbindMoveEvents(),this._unbindDropEvents(),this.dragStartTimer&&clearTimeout(this.dragStartTimer),this.options.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),$(this.dragEl,this.options.chosenClass,!1),this.dragEl.style["touch-action"]="",this.dragEl.style["will-change"]="",this.dragEl.draggable=!1,this.state.sortableDown&&this.state.sortableMove&&(this.differ.to.offset=D(this.dragEl),this.differ.to.rect=T(this.dragEl),e=(o=this.differ).from,o=o.to,e=e.offset.top!==o.offset.top||e.offset.left!==o.offset.left,(o=this.options.onDrop)&&"function"==typeof o&&o(e,t)),this._clearState(),this.ghost.destroy(this.differ.to.rect),c&&M(document.body,"user-select","")},_clearState:function(){this.dragEl=null,this.dropEl=null,this.state=new O,this.differ.destroy()}}).utils={getRect:T,getOffset:D,debounce:P,throttle:A,getParentAutoScrollElement:_},H}); |
{ | ||
"name": "sortable-dnd", | ||
"version": "0.2.5", | ||
"version": "0.2.6", | ||
"description": "JS Library for Drag and Drop, supports Sortable and Draggable", | ||
"main": "dist/sortable.min.js", | ||
"main": "dist/sortable.js", | ||
"files": [ | ||
@@ -7,0 +7,0 @@ "src", |
@@ -66,3 +66,3 @@ <p> | ||
| **method** | **Description** | | ||
| **Method** | **Description** | | ||
|--------------|--------------| | ||
@@ -76,3 +76,3 @@ | `destroy()` | Manually clear all the state of the component, using this method the component will not be draggable | | ||
| **option** | **type** | **default** | **Description** | | ||
| **Option** | **Type** | **Default** | **Description** | | ||
|-------------------|-------------------|-------------|--------------| | ||
@@ -85,3 +85,3 @@ | `animation` | `Number` | `150` | Animation speed moving items when sorting | | ||
| `onChange` | `Function` | `undefined` | The callback function when the dragged element changes position: <br /> `(from, to, event, originalEvent) => {}` | | ||
| `autoScroll` | `Boolean` | `true` | Automatic scrolling when moving to the edge of the container | | ||
| `autoScroll` | `Boolean` | `true` | Automatic scrolling when moving to the edge of the container, **for browsers that do not support HTML5 drag events** | | ||
| `scrollStep` | `Number` | `5` | The distance to scroll each frame when autoscrolling | | ||
@@ -91,5 +91,5 @@ | `scrollThreshold` | `Number` | `15` | Threshold to trigger autoscroll | | ||
**Other** | ||
**Others** | ||
| **option** | **type** | **default** | **Description** | | ||
| **Option** | **Type** | **Default** | **Description** | | ||
|-------------------|-------------------|-------------|--------------| | ||
@@ -96,0 +96,0 @@ | `disabled` | `Boolean` | `false` | Disables the sortable if set to true | |
@@ -19,3 +19,3 @@ import { getRect, setTransition, setTransform } from './utils.js' | ||
animationState.length = 0 // 重置 | ||
animationState.length = 0 // reset | ||
@@ -45,3 +45,3 @@ children.slice(start, end + 1).forEach(child => { | ||
el.offsetLeft // 触发重绘 | ||
el.offsetLeft // trigger repaint | ||
@@ -48,0 +48,0 @@ setTransition(el, `${animation}ms`) |
@@ -5,17 +5,21 @@ import { on, off } from './utils.js' | ||
return { | ||
_bindEventListener() { | ||
_bindDragEventListener() { | ||
this._onDrag = this._onDrag.bind(this) | ||
this._onMove = this._onMove.bind(this) | ||
this._onDrop = this._onDrop.bind(this) | ||
const { supportPointer, supportTouch } = this.options | ||
if (supportPointer) { | ||
on(this.rootEl, 'pointerdown', this._onStart) | ||
on(this.rootEl, 'pointerdown', this._onDrag) | ||
} else if (supportTouch) { | ||
on(this.rootEl, 'touchstart', this._onStart) | ||
on(this.rootEl, 'touchstart', this._onDrag) | ||
} else { | ||
on(this.rootEl, 'mousedown', this._onStart) | ||
on(this.rootEl, 'mousedown', this._onDrag) | ||
} | ||
}, | ||
_unbindEventListener() { | ||
off(this.rootEl, 'pointerdown', this._onStart) | ||
off(this.rootEl, 'touchstart', this._onStart) | ||
off(this.rootEl, 'mousedown', this._onStart) | ||
_unbindDragEventListener() { | ||
off(this.rootEl, 'pointerdown', this._onDrag) | ||
off(this.rootEl, 'touchstart', this._onDrag) | ||
off(this.rootEl, 'mousedown', this._onDrag) | ||
}, | ||
@@ -33,10 +37,2 @@ | ||
_bindUpEvents() { | ||
on(this.ownerDocument, 'pointerup', this._onDrop) | ||
on(this.ownerDocument, 'pointercancel', this._onDrop) | ||
on(this.ownerDocument, 'touchend', this._onDrop) | ||
on(this.ownerDocument, 'touchcancel', this._onDrop) | ||
on(this.ownerDocument, 'mouseup', this._onDrop) | ||
}, | ||
_unbindMoveEvents() { | ||
@@ -48,3 +44,3 @@ off(this.ownerDocument, 'pointermove', this._onMove) | ||
_unbindUpEvents() { | ||
_unbindDropEvents() { | ||
off(this.ownerDocument, 'pointerup', this._onDrop) | ||
@@ -55,4 +51,12 @@ off(this.ownerDocument, 'pointercancel', this._onDrop) | ||
off(this.ownerDocument, 'mouseup', this._onDrop) | ||
}, | ||
_unbindDragEvents() { | ||
if (this.nativeDraggable) { | ||
off(this.rootEl, 'dragstart', this._onDragStart) | ||
off(this.rootEl, 'dragover', this._onDragOver) | ||
off(this.rootEl, 'dragend', this._onDrop) | ||
} | ||
} | ||
} | ||
} |
@@ -43,3 +43,3 @@ import { css, getRect, toggleClass, setTransition, setTransform } from './utils.js' | ||
init(el, rect) { | ||
init(el, rect, append = true) { | ||
this.$el = el | ||
@@ -67,3 +67,3 @@ const { ghostClass, ghostStyle = {} } = this.options | ||
this.container.appendChild(this.$el) | ||
if (append) this.container.appendChild(this.$el) | ||
@@ -70,0 +70,0 @@ css(this.$el, 'transform-origin', (this.distance.x / parseInt(this.$el.style.width) * 100) + '% ' + (this.distance.y / parseInt(this.$el.style.height) * 100) + '%') |
import { | ||
on, | ||
off, | ||
css, | ||
@@ -15,4 +17,5 @@ matches, | ||
import { Ghost, Differ, State } from './Plugins.js' | ||
import AutoScroll from './Autoscroll.js' | ||
import Animation from './Animation.js' | ||
import Events from './events.js' | ||
import Events from './Events.js' | ||
@@ -39,26 +42,26 @@ // -------------------------------- Sortable ---------------------------------- | ||
const defaults = { | ||
autoScroll: true, // 拖拽到容器边缘时自动滚动 | ||
scrollStep: 5, // 每一帧滚动的距离 | ||
scrollThreshold: 15, // 自动滚动的阈值 | ||
autoScroll: true, // Auto scrolling when dragging to the edge of the container | ||
scrollStep: 5, // The distance to scroll each frame | ||
scrollThreshold: 15, // Autoscroll threshold | ||
delay: 0, // 定义鼠标选中列表单元可以开始拖动的延迟时间 | ||
delay: 0, // Defines the delay time after which the mouse-selected list cell can start dragging | ||
delayOnTouchOnly: false, // only delay if user is using touch | ||
disabled: false, // 定义是否此sortable对象是否可用,为true时sortable对象不能拖放排序等功能,为false时为可以进行排序,相当于一个开关 | ||
animation: 150, // 定义排序动画的时间 | ||
disabled: false, // Defines whether the sortable object is available or not. When it is true, the sortable object cannot drag and drop sorting and other functions. When it is false, it can be sorted, which is equivalent to a switch. | ||
animation: 150, // Define the timing of the sorting animation | ||
ghostAnimation: 0, // 拖拽元素销毁时动画效果 | ||
ghostClass: '', // 拖拽元素Class类名 | ||
ghostStyle: {}, // 拖拽元素样式 | ||
chosenClass: '', // 选中元素样式 | ||
ghostAnimation: 0, // Animation when the ghost element is destroyed | ||
ghostClass: '', // Ghost element class name | ||
ghostStyle: {}, // Ghost element style | ||
chosenClass: '', // Chosen element style | ||
draggable: undefined, // String: css选择器, Function: (e) => return true | ||
dragging: undefined, // 设置拖拽元素,必须为函数且必须返回一个 HTMLElement: (e) => return e.target | ||
onDrag: undefined, // 拖拽开始时触发的回调函数: () => {} | ||
onMove: undefined, // 拖拽过程中的回调函数: (from, to) => {} | ||
onDrop: undefined, // 拖拽完成时的回调函数: (from, to, changed) => {} | ||
onChange: undefined, // 拖拽元素改变位置的时候: (from, to) => {} | ||
draggable: undefined, // String: css selector, Function: (e) => return true | ||
dragging: undefined, // Set the drag element, must be a function and must return an HTMLElement: (e) => return e.target | ||
onDrag: undefined, // The callback function triggered when dragging starts: () => {} | ||
onMove: undefined, // The callback function during drag and drop: (from, to) => {} | ||
onDrop: undefined, // The callback function when the drag is completed: (from, to, changed) => {} | ||
onChange: undefined, // The callback function when dragging an element to change its position: (from, to) => {} | ||
fallbackOnBody: false, | ||
forceFallback: false, // 忽略 HTML5拖拽行为,强制回调进行 | ||
stopPropagation: false, // 阻止捕获和冒泡阶段中当前事件的进一步传播 | ||
forceFallback: false, // Ignore HTML5 drag and drop behavior, force callback to proceed | ||
stopPropagation: false, // Prevents further propagation of the current event in the capture and bubbling phases | ||
@@ -78,22 +81,12 @@ supportPointer: ('PointerEvent' in window) && !Safari, | ||
this.move = { x: 0, y: 0 } | ||
this.state = new State // 拖拽过程中状态记录 | ||
this.differ = new Differ() // 记录拖拽前后差异 | ||
this.ghost = new Ghost(this) // 拖拽时蒙版元素 | ||
this.dragEl = null // 拖拽元素 | ||
this.dropEl = null // 释放元素 | ||
this.state = new State // Status record during drag and drop | ||
this.differ = new Differ() // Record the difference before and after dragging | ||
this.ghost = new Ghost(this) // Mask element while dragging | ||
this.dragEl = null // Drag element | ||
this.dropEl = null // Drop element | ||
this.dragStartTimer = null // setTimeout timer | ||
this.autoScrollTimer = null | ||
Object.assign(this, Animation(), Events()) | ||
this._onStart = this._onStart.bind(this) | ||
this._onMove = this._onMove.bind(this) | ||
this._onDrop = this._onDrop.bind(this) | ||
this._bindEventListener() | ||
if (!window.requestAnimationFrame) { | ||
window.requestAnimationFrame = function(callback) { | ||
return setTimeout(callback, 17) | ||
} | ||
} | ||
Object.assign(this, Animation(), AutoScroll(), Events()) | ||
this._bindDragEventListener() | ||
} | ||
@@ -108,4 +101,8 @@ | ||
destroy: function() { | ||
this._unbindEventListener() | ||
this._clearState() | ||
this._unbindDragEventListener() | ||
// Remove draggable attributes | ||
Array.prototype.forEach.call(this.rootEl.querySelectorAll('[draggable]'), function (el) { | ||
el.removeAttribute('draggable') | ||
}) | ||
}, | ||
@@ -128,3 +125,3 @@ | ||
// -------------------------------- prepare start ---------------------------------- | ||
_onStart: function(/** Event|TouchEvent */evt) { | ||
_onDrag: function(/** Event|TouchEvent */evt) { | ||
if (/mousedown|pointerdown/.test(evt.type) && evt.button !== 0 || this.options.disabled) return // only left button and enabled | ||
@@ -141,12 +138,2 @@ | ||
const { delay, delayOnTouchOnly } = this.options | ||
if (delay && (!delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { | ||
clearTimeout(this.dragStartTimer) | ||
// delay to start | ||
this.dragStartTimer = setTimeout(() => this._onDrag(e, touch), delay) | ||
} else { | ||
this._onDrag(e, touch) | ||
} | ||
}, | ||
_onDrag: function(/** Event|TouchEvent */e, touch) { | ||
const { draggable, dragging } = this.options | ||
@@ -164,5 +151,3 @@ | ||
this._removeSelection() | ||
// 获取拖拽元素 | ||
// Get the dragged element | ||
if (dragging) { | ||
@@ -175,6 +160,6 @@ if (typeof dragging === 'function') this.dragEl = dragging(e) | ||
// 不存在拖拽元素时不允许拖拽 | ||
// No dragging is allowed when there is no dragging element | ||
if (!this.dragEl || this.dragEl.animated) return true | ||
// 获取拖拽元素在列表中的位置 | ||
// get the position of the dragged element in the list | ||
const { rect, offset } = getElement(this.rootEl, this.dragEl) | ||
@@ -186,25 +171,69 @@ this.move = { x: e.clientX, y: e.clientY } | ||
this._bindMoveEvents(touch) | ||
this._bindUpEvents(touch) | ||
// Solve the problem that `dragend` does not take effect when the `dragover` event is not triggered | ||
on(this.ownerDocument, 'pointerup', this._onDrop) | ||
on(this.ownerDocument, 'touchend', this._onDrop) | ||
on(this.ownerDocument, 'mouseup', this._onDrop) | ||
const { delay, delayOnTouchOnly } = this.options | ||
if (delay && (!delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { | ||
clearTimeout(this.dragStartTimer) | ||
// delay to start | ||
this.dragStartTimer = setTimeout(() => this._onStart(e, touch), delay) | ||
} else { | ||
this._onStart(e, touch) | ||
} | ||
}, | ||
// -------------------------------- is started ---------------------------------- | ||
_onStarted: function(e, /** originalEvent */evt) { | ||
if (!this.ghost.$el) { | ||
// 将初始化放到move事件中,防止与click事件冲突 | ||
const { rect } = this.differ.from | ||
this.ghost.init(this.dragEl.cloneNode(true), rect) | ||
_onStart: function(/** Event|TouchEvent */e, touch) { | ||
if (!this.nativeDraggable || touch) { | ||
this._bindMoveEvents(touch) | ||
on(this.ownerDocument, 'pointercancel', this._onDrop) | ||
on(this.ownerDocument, 'touchcancel', this._onDrop) | ||
} else { | ||
this.dragEl.draggable = true | ||
// add class for drag element | ||
toggleClass(this.dragEl, this.options.chosenClass, true) | ||
// 解决移动端无法拖拽问题 | ||
this.dragEl.style['touch-action'] = 'none' | ||
this.dragEl.style['will-change'] = 'transform' | ||
this._onDragStart = this._onDragStart.bind(this) | ||
this._onDragOver = this._onDragOver.bind(this) | ||
on(this.rootEl, 'dragstart', this._onDragStart) | ||
} | ||
// onDrag callback | ||
const { onDrag } = this.options | ||
if (onDrag && typeof onDrag === 'function') onDrag(this.dragEl, e, evt) | ||
// clear selection | ||
try { | ||
if (document.selection) { | ||
// Timeout neccessary for IE9 | ||
_nextTick(() => { document.selection.empty() }) | ||
} else { | ||
window.getSelection().removeAllRanges() | ||
} | ||
} catch (error) { | ||
// | ||
} | ||
}, | ||
if (Safari) css(document.body, 'user-select', 'none') | ||
// -------------------------------- drag event ---------------------------------- | ||
_onDragStart: function(evt) { | ||
// elements can only be dragged after firefox sets setData | ||
evt.dataTransfer.setData('te', evt.target.innerText) | ||
on(this.rootEl, 'dragover', this._onDragOver) | ||
on(this.rootEl, 'dragend', this._onDrop) | ||
}, | ||
_onDragOver: function(evt) { | ||
if (!this.state.sortableDown) return | ||
const { stopPropagation } = this.options | ||
stopPropagation && evt.stopPropagation && evt.stopPropagation() // prevent events from bubbling | ||
evt.preventDefault !== void 0 && evt.cancelable && evt.preventDefault() // prevent scrolling | ||
const { clientX, clientY } = evt | ||
const distanceX = clientX - this.move.x | ||
const distanceY = clientY - this.move.y | ||
if ((clientX !== void 0 && Math.abs(distanceX) <= 0) && (clientY !== void 0 && Math.abs(distanceY) <= 0)) { | ||
return | ||
} | ||
// truly started | ||
this._onStarted(evt, evt) | ||
if (evt.target === this.rootEl) return | ||
this._onChange(this, evt.target, evt, evt) | ||
}, | ||
@@ -226,6 +255,4 @@ | ||
this.state.sortableMove = e // sortable state move is active | ||
const { stopPropagation } = this.options | ||
stopPropagation && evt.stopPropagation && evt.stopPropagation() // 阻止事件冒泡 | ||
stopPropagation && evt.stopPropagation && evt.stopPropagation() // prevent events from bubbling | ||
evt.preventDefault !== void 0 && evt.cancelable && evt.preventDefault() // prevent scrolling | ||
@@ -236,7 +263,7 @@ | ||
// 拖拽过程中触发的回调 | ||
// onMove callback | ||
const { onMove } = this.options | ||
if (onMove && typeof onMove === 'function') onMove(this.differ.from, this.ghost.$el, e, evt) | ||
// 判断边界值 | ||
// boundary value judgment | ||
if (clientX < 0 || clientY < 0) return | ||
@@ -248,2 +275,3 @@ const { top, right, bottom, left } = getRect(this.rootEl) | ||
this._onChange(this, target, e, evt) | ||
// auto scroll | ||
@@ -255,2 +283,26 @@ this.autoScrollTimer && clearTimeout(this.autoScrollTimer) | ||
}, | ||
_onStarted: function(e, /** originalEvent */evt) { | ||
this.state.sortableMove = e // sortable state move is active | ||
if (!this.ghost.$el) { | ||
// Init in the move event to prevent conflict with the click event | ||
const { rect } = this.differ.from | ||
const ghostEl = this.dragEl.cloneNode(true) | ||
this.ghost.init(ghostEl, rect, !this.nativeDraggable) | ||
// add class for drag element | ||
toggleClass(this.dragEl, this.options.chosenClass, true) | ||
// solve the problem that the mobile cannot be dragged | ||
this.dragEl.style['touch-action'] = 'none' | ||
this.dragEl.style['will-change'] = 'transform' | ||
// onDrag callback | ||
const { onDrag } = this.options | ||
if (onDrag && typeof onDrag === 'function') onDrag(this.dragEl, e, evt) | ||
if (Safari) css(document.body, 'user-select', 'none') | ||
if (this.nativeDraggable) this._unbindDropEvents() | ||
} | ||
}, | ||
_onChange: debounce(function(_this, target, e, evt) { | ||
@@ -265,3 +317,3 @@ const { el, rect, offset } = getElement(_this.rootEl, target) | ||
if (clientX > left && clientX < right && clientY > top && clientY < bottom) { | ||
// 拖拽前后元素不一致时交换 | ||
// swap when the elements before and after the drag are inconsistent | ||
if (el !== _this.dragEl) { | ||
@@ -273,8 +325,8 @@ _this.differ.to = { node: _this.dropEl, rect, offset } | ||
const { onChange } = _this.options | ||
const _offset = getOffset(_this.dragEl) // 获取拖拽元素的 offset 值 | ||
const _offset = getOffset(_this.dragEl) | ||
// 元素发生位置交换时触发的回调 | ||
// onChange callback | ||
if (onChange && typeof onChange === 'function') onChange(_this.differ.from, _this.differ.to, e, evt) | ||
// 优先比较 top 值,top 值相同再比较 left | ||
// the top value is compared first, and the left is compared if the top value is the same | ||
if (_offset.top < offset.top || _offset.left < offset.left) { | ||
@@ -293,9 +345,10 @@ _this.rootEl.insertBefore(_this.dragEl, el.nextElementSibling) | ||
_onDrop: function(/** Event|TouchEvent */evt) { | ||
this._unbindDragEvents() | ||
this._unbindMoveEvents() | ||
this._unbindUpEvents() | ||
clearTimeout(this.dragStartTimer) | ||
this._unbindDropEvents() | ||
this.dragStartTimer && clearTimeout(this.dragStartTimer) | ||
const { stopPropagation } = this.options | ||
stopPropagation && evt.stopPropagation() // 阻止事件冒泡 | ||
evt.cancelable && evt.preventDefault() | ||
stopPropagation && evt.stopPropagation() | ||
evt.preventDefault && evt.preventDefault() | ||
@@ -306,5 +359,6 @@ // clear style and class | ||
this.dragEl.style['will-change'] = '' | ||
this.dragEl.draggable = false | ||
if (this.state.sortableDown && this.state.sortableMove) { | ||
// 重新获取一次拖拽元素的 offset 和 rect 值作为拖拽完成后的值 | ||
// re-acquire the offset and rect values of the dragged element as the value after the drag is completed | ||
this.differ.to.offset = getOffset(this.dragEl) | ||
@@ -314,3 +368,3 @@ this.differ.to.rect = getRect(this.dragEl) | ||
const { from, to } = this.differ | ||
// 通过 offset 比较是否进行了元素交换 | ||
// compare whether the element is swapped by offset | ||
const changed = from.offset.top !== to.offset.top || from.offset.left !== to.offset.left | ||
@@ -320,87 +374,9 @@ // onDrop callback | ||
if (onDrop && typeof onDrop === 'function') onDrop(changed, evt) | ||
this.ghost.destroy(to.rect) | ||
} | ||
this.differ.destroy() | ||
this.state = new State | ||
this._clearState() | ||
this.ghost.destroy(this.differ.to.rect) | ||
if (Safari) css(document.body, 'user-select', '') | ||
}, | ||
// -------------------------------- auto scroll ---------------------------------- | ||
_autoScroll: throttle(function(_this) { | ||
// check if is moving now | ||
if (!(_this.state.sortableDown && _this.state.sortableMove)) return | ||
const { clientX, clientY } = _this.state.sortableMove | ||
if (clientX === void 0 || clientY === void 0) return | ||
if (_this.scrollEl === _this.ownerDocument) { | ||
// does not support now | ||
} else { | ||
const { scrollTop, scrollLeft, scrollHeight, scrollWidth } = _this.scrollEl | ||
const { top, right, bottom, left, height, width } = getRect(_this.scrollEl) | ||
const { scrollStep, scrollThreshold } = _this.options | ||
// check direction | ||
const totop = scrollTop > 0 && clientY >= top && clientY <= (top + scrollThreshold) | ||
const toleft = scrollLeft > 0 && clientX >= left && clientX <= (left + scrollThreshold) | ||
const toright = (scrollLeft + width) < scrollWidth && clientX <= right && clientX >= (right - scrollThreshold) | ||
const tobottom = (scrollTop + height) < scrollHeight && clientY <= bottom && clientY >= (bottom - scrollThreshold) | ||
// scroll position | ||
const position = { x: scrollLeft, y: scrollTop } | ||
if (totop) { | ||
if (toleft) { | ||
// to top-left | ||
position.x = scrollLeft - scrollStep | ||
} else if (toright) { | ||
// to top-right | ||
position.x = scrollLeft + scrollStep | ||
} else { | ||
// to top | ||
position.x = scrollLeft | ||
} | ||
position.y = scrollTop - scrollStep | ||
} else if (tobottom) { | ||
if (toleft) { | ||
// to bottom-left | ||
position.x = scrollLeft - scrollStep | ||
} else if (toright) { | ||
// to bottom-right | ||
position.x = scrollLeft + scrollStep | ||
} else { | ||
// to bottom | ||
position.x = scrollLeft | ||
} | ||
position.y = scrollTop + scrollStep | ||
} else if (toleft) { | ||
// to left | ||
position.x = scrollLeft - scrollStep | ||
position.y = scrollTop | ||
} else if (toright) { | ||
// to right | ||
position.x = scrollLeft + scrollStep | ||
position.y = scrollTop | ||
} | ||
// if need to scroll | ||
if (totop || toleft || toright || tobottom) { | ||
requestAnimationFrame(() => { | ||
_this.scrollEl.scrollTo(position.x, position.y) | ||
_this._autoScroll(_this) | ||
}) | ||
} | ||
} | ||
}, 10), | ||
// -------------------------------- clear ---------------------------------- | ||
_removeSelection: function() { | ||
try { | ||
if (document.selection) { | ||
// Timeout neccessary for IE9 | ||
_nextTick(() => { document.selection.empty() }) | ||
} else { | ||
window.getSelection().removeAllRanges() | ||
} | ||
} catch (error) { | ||
// | ||
} | ||
}, | ||
_clearState: function() { | ||
@@ -410,3 +386,2 @@ this.dragEl = null | ||
this.state = new State | ||
this.ghost.destroy() | ||
this.differ.destroy() | ||
@@ -416,3 +391,3 @@ } | ||
Sortable.utils = { | ||
Sortable.prototype.utils = { | ||
getRect, | ||
@@ -419,0 +394,0 @@ getOffset, |
@@ -211,3 +211,3 @@ import { IE11OrLess } from './Brower.js' | ||
// 如果能直接在子元素中找到,返回对应的index | ||
// If it can be found directly in the child element, return | ||
const index = children.indexOf(el) | ||
@@ -222,3 +222,3 @@ if (index > -1) | ||
// children 中无法直接找到对应的dom时,需要向下寻找 | ||
// When the dom cannot be found directly in children, need to look down | ||
for (let i = 0; i < children.length; i++) { | ||
@@ -324,3 +324,3 @@ if (isChildOf(el, children[i])) { | ||
timer && clearTimeout(timer) | ||
immediate && !timer && fn.apply(context, args) // 首次立即触发 | ||
immediate && !timer && fn.apply(context, args) | ||
timer = setTimeout(function() { | ||
@@ -327,0 +327,0 @@ fn.apply(context, args) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
96174
13
2006