我正在尝试制作一个可以通过拖放重新定位的元素列表。第一个元素Box 1在100%的时间内都能正常工作。有时第二个框可以工作,但其他框都没有按预期工作。一旦你开始拖动它们,它们似乎会立即触发所有拖动事件。
如果重要的话,我正在使用最新的Chrome(第23版)。
var $questionItems = $('.question-item');
$questionItems
.on('dragstart', startDrag)
.on('dragend', removeDropSpaces)
.on('dragenter', toggleDropStyles)
.on('dragleave', toggleDropStyles);
function startDrag(){
console.log('dragging...');
addDropSpaces();
}
function toggleDropStyles(){
$(this).toggleClass('drag-over');
console.log(this);
}
function addDropSpaces(){
$questionItems.after('<div class="empty-drop-target"></div>');
console.log('drop spaces added');
}
function removeDropSpaces(){
$('.empty-drop-target').remove();
console.log('drop spaces removed');
}
这是HTML:
<div class="question-item" draggable="true">Box 1: Milk was a bad choice.</div>
<div class="question-item" draggable="true">Box 2: I'm Ron Burgundy?</div>
<div class="question-item" draggable="true">Box 3: You ate the entire wheel of cheese?</div>
<div class="question-item" draggable="true">Box 4: Scotch scotch scotch</div>
以下是我的代码的jsFiddle:http://jsfiddle.net/zGSpP/5/
答案 0 :(得分:25)
刚出现这个问题 - 这是一个Chrome错误,你不能在dragStart事件中操纵DOM,否则dragEnd会立即触发。我的解决方案原来是 - 使用setTimeout()并在你超时的函数内操作DOM。
答案 1 :(得分:8)
这似乎是一个Chrome错误:https://groups.google.com/a/chromium.org/forum/?fromgroups=#!msg/chromium-bugs/YHs3orFC8Dc/ryT25b7J-NwJ
答案 2 :(得分:6)
不确定它是否是一个bug,但我认为当你在dragstart处理程序中更改DOM时会出现问题。我认为第一个盒子工作的原因与它的位置在DOM中的其他盒子之前的事实有关,当你改变DOM时,第一个盒子的位置(?)不受影响,并且拖拉事件可靠地开火。
您需要稍微重构一下代码,并在dragenter事件处理程序中添加dropSpaces。您需要更改addDropSpaces方法以适应它将被多次调用的事实。
答案 3 :(得分:0)
jQuery的生活更轻松。这正是您所描述的,使用jQueryUI。
http://jqueryui.com/draggable/#sortable
允许排序。代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Draggable + Sortable</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<style>
ul { list-style-type: none; margin: 0; padding: 0; margin-bottom: 10px; }
li { margin: 5px; padding: 5px; width: 150px; }
</style>
<script>
$(function() {
$( "#sortable" ).sortable({
revert: true
});
$( "#draggable" ).draggable({
connectToSortable: "#sortable",
helper: "clone",
revert: "invalid"
});
$( "ul, li" ).disableSelection();
});
</script>
</head>
<body>
<ul>
<li id="draggable" class="ui-state-highlight">Drag me down</li>
</ul>
<ul id="sortable">
<li class="ui-state-default">Item 1</li>
<li class="ui-state-default">Item 2</li>
<li class="ui-state-default">Item 3</li>
<li class="ui-state-default">Item 4</li>
<li class="ui-state-default">Item 5</li>
</ul>
</body>
</html>
另见:http://jqueryui.com/sortable/
尝试手动添加事件,很长一段时间,例如:
$questionItems[0].on('dragstart', startDrag);
$questionItems[0].on('dragend', removeDropSpaces)
$questionItems[0].on('dragenter', toggleDropStyles)
$questionItems[0].on('dragleave', toggleDropStyles);
$questionItems[1].on('dragstart', startDrag);
$questionItems[1].on('dragend', removeDropSpaces)
$questionItems[1].on('dragenter', toggleDropStyles)
$questionItems[1].on('dragleave', toggleDropStyles);
等。只是为了看到效果?
答案 4 :(得分:-1)
更改此功能
function addDropSpaces()
{
$(this).after('<div class="empty-drop-target"></div>');
}
在您的版本中,您将在每个$ questionItems之后添加该div。
答案 5 :(得分:-1)
您需要阻止“事件”冒泡,以免引发其他事件。见https://developer.mozilla.org/en-US/docs/DOM/event.stopPropagation
对于startDrag,toggleDropStyles,removeDropSpaces函数,你会写这样的东西:
function startDrag(ev) {
ev.stopPropagation();
... your code here ...
}