2013-01-07 121 views
17

我試圖製作一個可以通過拖放重新定位的元素列表。第一個要素Box 1在100%的時間內工作得很好。有時候第二個盒子可以工作,但其他的都不能按預期工作。當你開始拖動它們時,他們似乎立刻就開始了所有的拖曳事件。dragend,dragenter和dragleave當我拖動時立即觸發

如果有問題,我正在使用最新的Chrome(v23)。

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

你使用jQuery的可拖動嗎?你在哪裏初始化元素爲可拖動的'element.draggable();'? – jbabey

+0

這真的很奇怪。您應該使用JQueryUI小部件事件作爲解決方法:http://jqueryui.com/draggable/ – sdespont

+0

jbabey:HTML5屬性'draggable = true' – Bill

回答

-1

改變此功能

function addDropSpaces() 
{ 
    $(this).after('<div class="empty-drop-target"></div>'); 
} 
在您的版本

要添加該分區後每個$ questionItems。

+0

目標是在每個框後面添加空格 – sdespont

+0

它似乎與該錯誤有關,但我確實希望在每個.question-item之後注入div,而不僅僅是當前的。 – Bill

1

生命是用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); 

等只是爲了看到效果?

+0

我真的需要能夠做的不僅僅是對列表進行排序,比如當一個項目被拖拽到另一個項目的頂部時,他們就會被分組。 – Bill

+0

你還可以,你只需通過jQuery來完成事件。 $(「.selector」).on(「drag」,function(event,ui){});和$(「.selector」).on(「dragstart」,function(event,ui){});它有回調,所以你仍然可以使用你已經建立的功能。 – SoluableNonagon

+0

另外,您是否嘗試手動將每個.on()添加到每個單獨的盒子項目?只是爲了看到效果? – SoluableNonagon

-1

您需要防止「事件」冒泡,因此它不會觸發其他事件。見https://developer.mozilla.org/en-US/docs/DOM/event.stopPropagation

有關的startDrag,toggleDropStyles,removeDropSpaces功能,你會寫是這樣的:

function startDrag(ev) { 
    ev.stopPropagation(); 
    ... your code here ... 
} 
+0

它似乎阻止執行其餘的功能? http://jsfiddle.net/zGSpP/11/ – Bill

4

不能確定它是否是一個錯誤或沒有,但我認爲問題是當你改變了在DOM在dragstart處理程序中。我認爲第一個盒子的工作原理與它在DOM中其他盒子之前的位置有關,並且當您更改DOM時,第一個盒子的位置(?)不受影響,拖動事件可靠地起火。

您需要稍微重構代碼,並在dragenter事件處理程序中添加dropSpaces。不過,您需要更改addDropSpaces方法以適應多次調用的事實。

22

剛纔有這個問題 - 這是一個Chrome bug,你不能在dragStart事件中操作DOM,否則dragEnd會立即觸發。對我來說,解決方案竟然是 - 使用setTimeout()並在超時函數內部操作DOM。

+0

這對我有效。此外,我在一個頁面變體上爲我工作的代碼相同,但不是另一個,它們之間唯一的區別是,操作元素的父元素在失敗時不是呈現(隱藏)。 –

相關問題