26

ドラッグ アンド ドロップで再配置できる要素のリストを作成しようとしています。最初の要素であるボックス 1 は、100% の確率で正常に機能します。2 番目のボックスが機能する場合もありますが、他のボックスは期待どおりに機能しません。ドラッグを開始するとすぐに、すべてのドラッグ イベントが一度に発生するようです。

問題がある場合は、最新の 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/

4

6 に答える 6

34

今この問題がありました - これは Chrome のバグです。dragStart イベントで DOM を操作してはなりません。そうしないと、dragEnd がすぐに発生します。私にとっての解決策は、 setTimeout() を使用し、タイムアウトする関数内で DOM を操作することであることが判明しました。

于 2013-12-22T20:42:08.930 に答える
10

Chrome のバグのようです: https://groups.google.com/a/chromium.org/forum/?fromgroups=#!msg/chromium-bugs/YHs3orFC8Dc/ryT25b7J-NwJ

于 2013-01-07T21:15:49.743 に答える
6

バグかどうかは定かではありませんが、dragstart ハンドラで DOM を変更すると問題が発生すると思います。最初のボックスが機能する理由は、その位置が DOM 内の他のボックスの前にあり、DOM を変更すると、最初のボックスの位置 (?) が影響を受けず、ドラッグドロップ イベントが発生するという事実と関係があると思われます。確実に着火。

コードをいくらかリファクタリングし、dragenter イベント ハンドラに dropSpaces を追加する必要があります。ただし、複数回呼び出されるという事実に対応するには、addDropSpaces メソッドを変更する必要があります。

于 2013-10-29T15:52:36.547 に答える
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); 

効果を確認するだけですか?

于 2013-01-07T21:21:10.230 に答える
-1

この機能を変更

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

あなたのバージョンでは、各 $questionItems の後にその div を追加しています。

于 2013-01-07T20:57:45.787 に答える
-1

「イベント」がバブルアップしないようにして、他のイベントが発生しないようにする必要があります。https://developer.mozilla.org/en-US/docs/DOM/event.stopPropagationを参照してください。

startDrag、toggleDropStyles、removeDropSpaces 関数の場合、次のように記述します。

function startDrag(ev) {
   ev.stopPropagation();
   ... your code here ...
}
于 2013-01-07T21:21:26.923 に答える