自定义拖放实现
Custom drag drop implementation
我正在推出一个自定义拖放实现,它是 Dragula 库的简化版本。这是我的小提琴:
德拉古拉:http://jsfiddle.net/8m4jrfwn/
使用我的自定义拖放实现:http://jsfiddle.net/7wLtojs4/1/
我看到的问题是我的自定义拖放实现有点不自由。我希望用户只能使用 class 框放在另一个 div 的顶部或底部。我怎样才能使这成为可能?代码在这里:
function handleMouseDown(e) {
window.dragging = {};
dragging.pageX = e.pageX;
dragging.pageY = e.pageY;
dragging.elem = this;
dragging.offset = $(this).offset();
$('body')
.on('mouseup', handleMouseUp)
.on('mousemove', handleDragging);
}
function handleDragging(e) {
let left = dragging.offset.left + (e.pageX - dragging.pageX);
let top = dragging.offset.top + (e.pageY - dragging.pageY);
$(dragging.elem)
.offset({top: top, left: left});
}
function handleMouseUp() {
$('body')
.off('mousemove', handleDragging)
.off('mouseup', handleMouseUp);
}
let boxElement = '.item';
$(boxElement).mousedown(handleMouseDown);
关于 mouseup 事件会发生什么,我在这里没有看到任何逻辑。看来您需要在 mouseup 上检测元素的新顺序,然后交换它们的位置。
为此你应该知道所有这些的位置。在 mouseup 上,您可以根据新位置对它们重新排序。
在我的实现中(https://jsfiddle.net/jaromudr/c99oueg5/)我使用了下一个逻辑:
onMove(draggable) {
const sortedDraggables = this.getSortedDraggables()
const pinnedPositions = sortedDraggables.map((draggable) => draggable.pinnedPosition)
const currentIndex = sortedDraggables.indexOf(draggable)
const targetIndex = indexOfNearestPoint(pinnedPositions, draggable.position, this.options.radius, getYDifference)
if (targetIndex !== -1 && currentIndex !== targetIndex) {
arrayMove(sortedDraggables, currentIndex, targetIndex)
this.bubling(sortedDraggables, draggable)
}
}
bubling(sortedDraggables, currentDraggable) {
const currentPosition = this.startPosition.clone()
sortedDraggables.forEach((draggable) => {
if (!draggable.pinnedPosition.compare(currentPosition)) {
if (draggable === currentDraggable && !currentDraggable.nativeDragAndDrop) {
draggable.pinnedPosition = currentPosition.clone()
} else {
draggable.pinPosition(currentPosition, (draggable === currentDraggable) ? 0 : this.options.timeExcange)
}
}
currentPosition.y = currentPosition.y + draggable.getSize().y + this.verticalGap
})
}
在移动中,我们检测列表中的位置是否已更改并将其他 draggables
移动到它们的新位置。
在拖动结束时,我们只需将 currentDraggable 移动到 pinnedPosition
我正在推出一个自定义拖放实现,它是 Dragula 库的简化版本。这是我的小提琴:
德拉古拉:http://jsfiddle.net/8m4jrfwn/
使用我的自定义拖放实现:http://jsfiddle.net/7wLtojs4/1/
我看到的问题是我的自定义拖放实现有点不自由。我希望用户只能使用 class 框放在另一个 div 的顶部或底部。我怎样才能使这成为可能?代码在这里:
function handleMouseDown(e) {
window.dragging = {};
dragging.pageX = e.pageX;
dragging.pageY = e.pageY;
dragging.elem = this;
dragging.offset = $(this).offset();
$('body')
.on('mouseup', handleMouseUp)
.on('mousemove', handleDragging);
}
function handleDragging(e) {
let left = dragging.offset.left + (e.pageX - dragging.pageX);
let top = dragging.offset.top + (e.pageY - dragging.pageY);
$(dragging.elem)
.offset({top: top, left: left});
}
function handleMouseUp() {
$('body')
.off('mousemove', handleDragging)
.off('mouseup', handleMouseUp);
}
let boxElement = '.item';
$(boxElement).mousedown(handleMouseDown);
关于 mouseup 事件会发生什么,我在这里没有看到任何逻辑。看来您需要在 mouseup 上检测元素的新顺序,然后交换它们的位置。
为此你应该知道所有这些的位置。在 mouseup 上,您可以根据新位置对它们重新排序。
在我的实现中(https://jsfiddle.net/jaromudr/c99oueg5/)我使用了下一个逻辑:
onMove(draggable) {
const sortedDraggables = this.getSortedDraggables()
const pinnedPositions = sortedDraggables.map((draggable) => draggable.pinnedPosition)
const currentIndex = sortedDraggables.indexOf(draggable)
const targetIndex = indexOfNearestPoint(pinnedPositions, draggable.position, this.options.radius, getYDifference)
if (targetIndex !== -1 && currentIndex !== targetIndex) {
arrayMove(sortedDraggables, currentIndex, targetIndex)
this.bubling(sortedDraggables, draggable)
}
}
bubling(sortedDraggables, currentDraggable) {
const currentPosition = this.startPosition.clone()
sortedDraggables.forEach((draggable) => {
if (!draggable.pinnedPosition.compare(currentPosition)) {
if (draggable === currentDraggable && !currentDraggable.nativeDragAndDrop) {
draggable.pinnedPosition = currentPosition.clone()
} else {
draggable.pinPosition(currentPosition, (draggable === currentDraggable) ? 0 : this.options.timeExcange)
}
}
currentPosition.y = currentPosition.y + draggable.getSize().y + this.verticalGap
})
}
在移动中,我们检测列表中的位置是否已更改并将其他 draggables
移动到它们的新位置。
在拖动结束时,我们只需将 currentDraggable 移动到 pinnedPosition