无法触发丢弃事件(是的,我在拖动中阻止了默认())



我正在开发一个可拖动HTML5列表的实现,但遇到了麻烦。

基本上,每当我在一个元素上拖动时,我都会在刚输入的元素之前或之后插入正在拖动的元素。这意味着,当您四处移动鼠标时,元素会一直移动到鼠标下方的位置。(我在元素上设置了visibility: hidden,所以它显示为空白。)当你放下元素时,我会向服务器发送一个AJAX调用,描述元素在服务器上执行移动的位置。

问题是,无论出于何种原因,drop事件永远不会触发(我的处理程序中的断点永远不会被命中),并且拖动图像会捕捉回它开始的位置。(当然,元素已经在页面上移动了,所以它会重新出现在新位置,但由于drop从未启动,因此服务器永远不会收到更改通知。)有人知道发生了什么吗?通常的答案是"你需要在draginter/dragover中调用preventDefault()",但我已经在这么做了。

我使用的是jQuery 1.10.2,在Safari 7.0.1和Firefox 26.0中都看到了这种行为。值得一提的是,Rails 4.0.2是我这个项目的框架,我使用的是jquery_ujs和turbolinks。

相关代码:

var draggingLI;
$('ol[data-passage-id]').find('li > a').attr('draggable', 'true')
.on('dragstart', function (ev) {
draggingLI = $(ev.target).closest("li")[0];
ev.originalEvent.dataTransfer.effectAllowed = 'move';
ev.originalEvent.dataTransfer.setData('text/plain', ev.target.href);
ev.originalEvent.dataTransfer.setData('text/uri-list', ev.target.href);
})
.on('dragenter', function (ev) {
ev.originalEvent.dataTransfer.dropEffect = 'move'; 
$(draggingLI).css('visibility', 'hidden');
if(canDropIn(ev.target)) {
var droppingLI = $(ev.target).closest("li")[0];
if(draggingLI == droppingLI) {
// do nothing
}
if(draggingLI.nextElementSibling == droppingLI) {
// We want to move the dragging element below this element.
$(droppingLI).after(draggingLI);
}
else {
// We want to move the dragging element above this element.
$(droppingLI).before(draggingLI);
}
ev.preventDefault();
ev.stopPropagation();
return false;
}
})
.on('dragover', function (ev) {
if(canDropIn(ev.target)) {
ev.preventDefault();
ev.stopPropagation();
return false;
}
})
.on('drop', function (ev) {
sendMovedItem(draggingLI);
ev.preventDefault();
ev.stopPropagation();
return false;
})
.on('dragend', function (ev) {
$(draggingLI).css('visibility', '');
});

canDropIn()当前是一个总是返回true的存根。sendMovedItem()是执行AJAX调用的函数。控制台上没有错误。

问题似乎是由我移动拖动元素本身的策略引起的;我不确定是因为在拖动元素时移动元素会导致浏览器出现问题,还是因为不允许拖放原始元素。我通过完全隐藏原始元素,然后插入一个可以移动的占位符元素来解决这个问题。(您必须将draginter/dragover/drop处理程序附加到占位符,因为所有成功的drop都在占位符上结束。)

不过,如果有人有想法的话,我仍然更喜欢一个不需要占位符的解决方案!

相关内容

最新更新