Skip to main content
 首页 » 编程设计

jQuery 拖放模拟不适用于最后一个可拖动的对象

2026年07月28日7飞鱼

我正在尝试使用 jquery-simulate-ext 来模拟拖放模拟jquery-ui的插件.

在详细介绍场景之前,让我向您展示 js fiddle here .

我有 3 列 div。在第一列中,我有 3 个带有国家/地区名称的可拖动元素,在第二列中有 3 个空白 div 的可拖动元素,在第三列中有 3 个带有城市名称的普通 div 元素。因此,在第一列中的所有可拖动对象都放置在第二列上之后,第二列和第三列行将产生乡村与城市关系的感觉。

但问题是模拟完成后,第一个和第二个可拖动对象被放置在预期的可放置对象上,但第三个可拖动对象只是粘在鼠标上而不是放置在可放置对象上。要找到这种行为,在加载上述 js fiddle 页面后,只需将鼠标光标移动到结果部分,您将看到可拖动对象也随着鼠标移动。您必须单击某处才能使可拖动部分位于可放置或可拖动部分(取决于您单击的区域)。这种情况仅在 Firefox 中发生,而在 chrome 中,可拖动对象仅在适当的可放置部分内随光标移动,然后自动位于其中。

我想要的是:与其他可拖动对象一样,第三个可拖动对象不应随着鼠标的移动而移动,而应自动位于所需的可拖动对象上。

代码说明:

每个具有 draggable_div 类的可拖动 div 都有一个属性 data-index (值 1、2、3 等)。同样的情况也适用于 droppable div (带有类 droppable_blank)。现在,在 JS 代码的开头,我有以下行:

answers_found='[1,2,3]'; 

这些基本上是可拖动对象中的data-index值。值的顺序仅显示可拖动对象位于可放置对象上时的 data-index 值的顺序。在上述情况下,第一个值为 1,因此第一个(不是第二个或第三个)可拖动对象将位于第一个可放置对象上。同样,第二个和第三个可拖动对象将连续位于第二个和第三个可放置对象上。

代码执行以下for循环

for(var i =0; i<answers_found.length; i++){ 

从 answers_found 数组中获取每个值。该值是可拖动的 data-index 属性值。然后为 call_trigger_drop 函数提供 2 个参数:

call_trigger_drop(parseInt(answer_found_indiv),droppable_index); 

第一个是可拖动索引,第二个是相应可放置索引,即可拖动对象将位于可放置对象上。实际模拟通过以下几行进行:

draggable.simulate("drag", { 
                dx: dx, 
                dy: dy 
            }); 

TL;博士:

第一列的 Draggables 被模拟放置在第二列的 droppables 上,而第三列只是普通的 div。拖放模拟之后,第三个可拖动项不会位于 Firefox 中的第三个可拖放项上,而是会随着光标移动,直到发生单击为止。 如何让它像其他可拖动对象一样自动放置在可放置对象上?

编辑:
如果你想得到一个普通网页而不是js-fiddle的结果,你可以找到 here 。

console = {}; 
console.log = function(){}; 
window.console = console; 
drag_stop_counter = 0; 
answers_found = '[3,2,1]'; 
answer_all_zero = 0; //REMOVABLE 
if (answers_found != "".trim()) { 
  answers_found = $.parseJSON(answers_found); 
  answer_all_zero = 1; 
  for (var i = 0; i < answers_found.length; i++) { 
    if (parseInt(answers_found[i]) != 0) { 
      answer_all_zero = 0; 
      break; 
    } 
  } //end of for loop 
} 
total_answers_found = answers_found.length; 
total_actual_answers_found = 0; 
for (var i = 0; i < answers_found.length; i++) { 
  if (parseInt(answers_found[i])) { 
    ++total_actual_answers_found; 
  } 
} //end of for loop 
answers = []; 
answers_made_for_insert = []; 
question_id = 2901; 
//Following function is triggered 
//when the dNd component is starting the drop 
//event 
function trigger_drop(draggable_elem_index, droppable_elem_index) { 
  if (draggable_elem_index && droppable_elem_index) { 
    if (window.console) { 
      console.log("from within trigger_drop : draggable_elem_index = " + draggable_elem_index + " droppable_elem_index=  " + droppable_elem_index); 
    } 
    // var draggable = $(".draggable_container_indiv .draggable_div").eq(draggable_elem_index-1).draggable(), 
    var draggable = $(".draggable_container_indiv").eq(draggable_elem_index - 1).find(".draggable_div").draggable(), 
      droppable = $("#droppable_slots .droppable_blank").eq(droppable_elem_index - 1).droppable(), 
      droppableOffset = droppable.offset(), 
      draggableOffset = draggable.offset(), 
      dx = droppableOffset.left - draggableOffset.left, 
      dy = droppableOffset.top - draggableOffset.top; 
    draggable.simulate("drag", { 
      dx: dx, 
      dy: dy 
    }); 
  } // end of if(draggable_elem_index && droppable_elem_index){ 
} // end of function trigger_drop( 
 
//answers stored in array for insertion in DB 
function make_answers_for_insert(answer_given) { 
  answers_made_for_insert.push(answer_given); 
} //end of function answers_for_insert 
//finds answers from array 
function find_answers() { 
  answers = []; 
  $('input[name="' + question_id + '[]"]').each(function() { 
    $elem = $(this); 
    var value_found = $elem.val().trim(); 
    if (value_found == "".trim()) { 
      value_found = "0"; 
    } 
    // if(value_found!="".trim()){ 
    answers.push(value_found); 
    // } 
  }); 
  //alert("answers made "+answers); 
  if (window.console) { 
    console.log("answers from find_answers = "); 
    console.log(answers); 
  } 
} //end of function find_answers 
 
function call_trigger_drop(answer_found_indiv, droppable_index) { 
  trigger_drop(answer_found_indiv, droppable_index); 
} 
function insert_answer() { 
  if (window.console) { 
    console.log(" can_submit in insert_answer = " + can_submit); 
  } 
  if (can_submit) { 
    can_submit = 0 
    $("#draggable .draggable_div").draggable('disable'); 
    //ui.draggable.draggable({disabled: true}); 
    $('#droppable_slots li').find('.ui-draggable').draggable({ 
      disabled: true 
    }); 
    answers = []; 
    $('input[name="' + question_id + '[]"]').each(function() { 
      $elem = $(this); 
      var value_found = $elem.val().trim(); 
      if (value_found == "".trim()) { 
        value_found = "0"; 
      } 
      // if(value_found!="".trim()){ 
      answers.push(value_found); 
      // } 
    }); 
    answers = JSON.stringify(answers); 
    if (window.console) { 
      console.log("answers from insert_answers = "); 
      console.log(answers); 
    } 
    //ajax call for insertion 
  } // end of if(can_submit){ 
} // end of function insert_anwers 
$(document).ready(function() { 
  answer_status = 0; 
  review_table_status = 0; 
  $('input[name="' + question_id + '[]"]').each(function() { 
    var dnd_value_found = $(this).val().trim(); 
    if (window.console) { 
      console.log(" dnd_value_found = " + dnd_value_found); 
    } 
    if (dnd_value_found != "".trim()) { 
 
      answer_status = 1; 
      review_table_status = 1; 
      return false; 
    } 
  }); // end of each 
  var draggable_counter = 0; 
  $(".draggable_container_indiv").each(function() { 
    // $draggable_elem=$(this); 
    $draggable_elem = $(".draggable_div").eq(draggable_counter); 
    var $droppable_elem = $(".droppable_content_indiv").eq(draggable_counter); 
    var $draggable_container_indiv_elem = $(".draggable_container_indiv").eq(draggable_counter); 
    var $droppable_blank_elem = $(".droppable_blank").eq(draggable_counter); 
    var droppable_height = $droppable_elem.css('height'); 
    var draggable_height = $draggable_elem.css('height'); 
    var droppable_width = $droppable_elem.css('width'); 
    var draggable_width = $draggable_elem.css('width'); 
    var height_more = 0; 
    if (parseInt(draggable_height) > parseInt(droppable_height)) { 
      height_more = draggable_height; 
    } else { 
      height_more = droppable_height; 
    } 
    var width_more = 0; 
    if (parseInt(draggable_width) > parseInt(droppable_width)) { 
 
      width_more = draggable_width; 
 
    } else { 
      width_more = droppable_width; 
    } 
 
    if (window.console) { 
 
      console.log(" draggable_height " + draggable_height + " droppable_height = " + droppable_height + " height_more = " + height_more); 
 
    } 
    $draggable_elem.css({ 
      'height': height_more 
    }); 
    $droppable_elem.css({ 
      'height': height_more 
    }); 
    $droppable_blank_elem.css({ 
      'height': height_more 
    }); 
    $draggable_container_indiv_elem.css({ 
      'height': height_more 
    }); 
    //$('.draggable_container_indiv').css({'height':22});// hhhhhhhh 
 
    $draggable_elem.css({ 
      'width': width_more 
    }); 
    $droppable_elem.css({ 
      'width': width_more 
    }); 
    $droppable_blank_elem.css({ 
      'width': width_more 
    }); 
    $draggable_container_indiv_elem.css({ 
      'width': width_more 
    }); 
    $droppable_elem.find(".ui-draggable").css({ 
      'width': width_more 
    }); 
 
 
    ++draggable_counter; 
 
 
 
  }); 
 
 
  $("#draggable .draggable_div").draggable({ 
    scroll: false, 
    revert: true, 
    // helper: 'clone', 
    //appendTo: 'body', 
    start: function() { 
 
      if (window.console) { 
 
        console.log(" draggable started ....... "); 
      } 
 
      $(this).css({ 
        display: 'none' 
      }); 
 
 
    }, 
    stop: function() { 
 
 
      $(this).css({ 
        display: 'block' 
      }); 
      var draggableIndex = $(this).data('index'); 
      ++drag_stop_counter; 
      if (window.console) { 
 
        console.log(" draggable stopped = " + drag_stop_counter); 
 
        console.log("draggable index in stop = " + draggableIndex); 
 
      } 
 
 
      var droppableIndex = $('#droppable_slots li').find('.ui-draggable[data-index=' + draggableIndex + ']').closest('.slot').data('index'); 
 
      var index_found = $.inArray(draggableIndex + "", answers); 
 
      if (window.console) { 
        console.log("inside stop  draggableIndex = " + draggableIndex + " after dropped ..... index_found = " + index_found); 
 
      } 
 
 
 
    }, 
    revert: function(dropped) { 
 
 
      var dropped = dropped && dropped.hasClass('slot'); //fix duplicated IDs 
      if (!dropped) { 
        $(this).appendTo($(this).data('originalParent')) 
      } 
      return !dropped; 
 
 
    }, 
    revertDuration: 0, //removed glitched effect 
    helper: function() { 
      return $(this).clone().appendTo('body').show(); 
    }, 
    containment: '.sel_screen_left' 
  }).each(function() { 
    $(this).data('originalParent', $(this).parent()) 
  }); 
 
 
  $("#droppable_slots li").droppable({ 
    //        tolerance:'pointer', 
    tolerance: 'intersect', 
    drop: function(event, ui) { 
 
      $(this).trigger('dropthis', [event, ui]); //REMOVABLE 
 
      $(this).trigger("dropthis", [{}, { 
        draggable: ui.draggable 
      }]); //REMOVABLE 
 
 
 
      var $this = $(this); 
      if ($this.find('.ui-draggable').length) return; //don't overwrite occupied spot 
      //$this.empty(); 
      $this.append(ui.draggable); 
 
      var width = $this.width(); 
      var height = $this.height(); 
      var cntrLeft = (width / 2) - (ui.draggable.width() / 2); 
      var cntrTop = (height / 2) - (ui.draggable.height() / 2); 
 
      ui.draggable.css({ 
        left: cntrLeft + "px", 
        top: cntrTop + "px" 
      }); 
 
      var draggableIndex = parseInt(ui.draggable.data("index")); 
      var droppableIndex = parseInt($(this).data("index")); 
 
      if (window.console) { 
 
        console.log(" draggableIndex = " + draggableIndex + " droppableIndex = " + droppableIndex + " question_id = " + question_id); 
 
      } 
 
 
      if (window.console) { 
        console.log("droppable question_id = " + question_id); 
        console.log(" droppable drop has  draggableIndex answer  = " + draggableIndex); 
 
      } 
 
 
 
 
      if (window.console) { 
        console.log(" inside drop .......................... "); 
 
      } 
 
 
      var index_found = $.inArray(draggableIndex + "", answers); 
 
      if (window.console) { 
        console.log(" draggableIndex = " + draggableIndex + " after dropped ..... index_found = " + index_found); 
 
      } 
      if (index_found != -1) { 
        answers[index_found] = ''; 
 
        $('input[name="' + question_id + '[]"]').eq(index_found).val(''); 
      } 
 
 
 
 
 
 
      $(".droppable_blank[data-index=" + droppableIndex + "]").trigger('click'); 
 
      if (window.console) { 
        console.log(" droppable_blank clicked   droppableIndex = " + droppableIndex); 
 
      } 
 
 
 
    }, 
    out: function(event, ui) { 
 
 
    }, 
    over: function(event, ui) { 
 
    } 
  }); 
 
 
 
  if (window.console) { 
 
    console.log("DnD ANSWERS  found = "); 
    console.log(answers_found); 
 
  } 
 
 
  answer_found_indiv = 0; 
  droppable_index = 0; 
  for (var i = 0; i < answers_found.length; i++) { 
 
    //return false; 
 
    if (window.console) { 
 
      console.log(" iterating all answers:  DnDDnDDnDDnDDnD dragndrop draggable index = " + answers_found[i] + " droppable index = " + (i + 1)); 
 
    } 
 
    var droppable_index = i + 1; 
    var answer_found_indiv = parseInt(answers_found[i]); 
    if (answer_found_indiv == 0) { 
 
      if (window.console) { 
 
        console.log(" answer_found_indiv 000000000000000000"); 
 
      } 
 
    } else if (answer_found_indiv) { 
 
      if (window.console) { 
 
        console.log("Trigger Drop = " + answer_found_indiv, " droppable_index = " + droppable_index); 
 
      } 
 
      call_trigger_drop(parseInt(answer_found_indiv), droppable_index); 
 
    } 
 
 
 
  } // end of for loop 
 
 
 
 
});
.noselect { 
    -webkit-touch-callout: none; /* iOS Safari */ 
    -webkit-user-select: none; /* Safari */ 
    -khtml-user-select: none; /* Konqueror HTML */ 
    -moz-user-select: none; /* Firefox */ 
    -ms-user-select: none; /* Internet Explorer/Edge */ 
    user-select: none; /* Non-prefixed version, currently 
                                  supported by Chrome and Opera */ 
} 
 
.draggable_container_indiv{ 
 
    border: 1px solid green; 
 
} 
 
#draggable .draggable_div { 
    margin-left: -60px; 
    padding: 10px; 
} 
.droppable_blank{ 
    /*line-height: 40px;*/ 
    vertical-align: middle; 
} 
#draggable li, #draggable .draggable_div, #droppable_slots li, .draggable_div{ 
    list-style: none; 
} 
.dragndrop-questions ul.option-left li{ 
    padding-top: 0; 
} 
.match-questions ul.option-left li, .dragndrop-questions ul.option-left li{ 
    font-size: 14px; 
    color: #656f7d; 
    position: relative; 
    padding-left: 60px; 
    min-height: 40px; 
} 
 
.draggable_container_indiv{ 
 
    margin-bottom: -10px !important; 
}
<link href="https://epractice.lcbsdhaka.com/mytest/css/bootstrap.min.css" rel="stylesheet"> 
    <link href="https://epractice.lcbsdhaka.com/mytest/js/jquery-ui-1.12.1.custom/jquery-ui.css"></link> 
    <script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-1.12.4.js"></script> 
 
 
    <script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script> 
 
    <script src="https://epractice.lcbsdhaka.com/mytest/js/bootstrap.min.js"></script> 
 
    <script src="https://epractice.lcbsdhaka.com/mytest/js/jquery.simulate.js"></script> 
    <script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-simulate-ext/src/jquery.simulate.ext.js"></script> 
    <script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-simulate-ext/src/jquery.simulate.drag-n-drop.js"></script> 
 
 
<script src="https://epractice.lcbsdhaka.com/mytest/js/bootstrap.min.js"></script> 
 
<script src="https://epractice.lcbsdhaka.com/mytest/js/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script> 
 
 
 
<div class="dragndrop-questions row"> 
 
 
 
  <div> 
    <div style="width:30%; float: left; "> 
      <ul class="option option-left" id="draggable"> 
 
        <li  class="draggable_container_indiv noselect"> 
          <div class="draggable_div" data-index="1"> 
 
            USA 
          </div> 
        </li> 
 
        <li  class="draggable_container_indiv noselect"> 
          <div class="draggable_div" data-index="2"> 
 
            JAPAN 
          </div> 
        </li> 
 
        <li  class="draggable_container_indiv noselect"> 
          <div class="draggable_div" data-index="3"> 
 
            CHINA 
          </div> 
        </li> 
 
      </ul> 
    </div> 
    <div  style="width:65%; float: right; margin-right: 10px;"> 
      <ul class="option option-right" id="droppable_slots"> 
 
 
        <div class="row "> 
          <div style="width:45%; float: left; margin-left:10px; border: 1px solid red;"> 
 
            <li class="slot droppable_blank noselect" data-index="1"> 
 
 
            </li> 
 
          </div> 
          <div style="width:48%; float: right; border: 1px solid yellow;"> 
 
 
            <li class="droppable_content_indiv noselect"> 
              <p> 
                NewYork 
              </p> 
 
 
            </li> 
          </div> 
        </div> 
        <!--end of class row --> 
 
        <div class="row "> 
          <div style="width:45%; float: left; margin-left:10px; border: 1px solid red;"> 
 
            <li class="slot droppable_blank noselect" data-index="2"> 
 
 
            </li> 
 
          </div> 
          <div style="width:48%; float: right; border: 1px solid yellow;"> 
 
 
            <li class="droppable_content_indiv noselect"> 
              <p> 
                Tokyo 
              </p> 
 
            </li> 
          </div> 
        </div> 
        <!--end of class row --> 
 
 
        <div class="row "> 
          <div style="width:45%; float: left; margin-left:10px; border: 1px solid red;"> 
 
            <li class="slot droppable_blank noselect" data-index="3"> 
 
 
            </li> 
 
          </div> 
          <div style="width:48%; float: right; border: 1px solid yellow;"> 
 
 
            <li class="droppable_content_indiv noselect"> 
              <p> 
                Beijing 
              </p> 
 
            </li> 
          </div> 
        </div> 
        <!--end of class row --> 
 
 
 
 
      </ul> 
    </div> 
 
    <div class="" style="clear: both;"></div> 
  </div> 
 
 
</div> 
<!-- end of class dragndrop-questions-->

请您参考如下方法:

这是因为它只模拟drag事件,而没有drop,请使用drag-n-drop代替。

draggable.simulate("drag-n-drop", {dx: dx,  dy: dy});