【问题标题】:How can I drag-and-drop cell contents within a table with dynamically added rows and cells?如何在动态添加行和单元格的表格中拖放单元格内容?
【发布时间】:2020-08-13 00:02:49
【问题描述】:

我在拖放动态生成的表格时遇到了困难。该界面根据用户选择呈现表格行和单元格的网格。

我想做的是让用户能够将一个单元格、一个 div 或 span 的内容拖到另一个单元格中。

近 6 年前的这段对话与我想要做的很接近。但它无法处理表具有动态添加的行的情况。 Drag and Drop table cell contents

$(function() {
  $('.event').on("dragstart", function(event) {
    var dt = event.originalEvent.dataTransfer;
    dt.setData('Text', $(this).attr('id'));
  });
  $('table td').on("dragenter dragover drop", function(event) {
    event.preventDefault();
    if (event.type === 'drop') {
      var data = event.originalEvent.dataTransfer.getData('Text', $(this).attr('id'));
      de = $('#' + data).detach();
      de.appendTo($(this));
    };
  });
  $('#addRow').on('click', function() {
    $('#targetTable > tbody:last-child').append('<tr><td></td><td></td><td></td></tr>');
  });
});

这个基于该代码的示例演示了我的问题。 https://jsfiddle.net/Stormjack/osvu6mea/11/

您可以成功地将蓝色块拖放到前两行中的任何单元格中。但是使用“添加行”按钮添加一个新行,您不能将该块放入任何新行。您仍然可以将可拖动范围移动到前两行中的不同单元格。但它无法拖入新行。

我怎样才能克服这个限制?我很乐意使用 HTML5 或 JavaScript 或 jQuery 或其他客户端库的任意组合。感谢您的帮助。


这是我的解决方案,基于 saintvixalien 的帮助。

$(function() {
 initDragAndDrop();
 $('#addRow').on('click', function() {
    $('#targetTable > tbody:last-child').append('<tr><td></td><td></td><td></td></tr>');
    clearDragAndDrop();
    initDragAndDrop();
 });
});

function clearDragAndDrop() {
 $('.event').off();
 $('table td').off('dragenter dragover drop');
}

function initDragAndDrop() {
 $('.event').on('dragstart', function(event) {
    var dt = event.originalEvent.dataTransfer;
    dt.setData('Text', $(this).attr('id'));
 });
 $('table td').on('dragenter dragover drop', function(event) {
    event.preventDefault();
    if (event.type === 'drop') {
      var data = event.originalEvent.dataTransfer.getData('Text', $(this).attr('id'));
      de = $('#' + data).detach();
      de.appendTo($(this));
    }
 });
}

https://jsfiddle.net/Stormjack/osvu6mea/15/

【问题讨论】:

    标签: javascript html jquery drag-and-drop


    【解决方案1】:

    问题在于,当您添加 "dragenter dragover drop" 事件侦听器时,只有 2 行,这意味着对于添加的每个新行,您都必须向其中添加事件侦听器。

    注意:如果您每次添加新行时都运行事件侦听过程,那么您最终会得到具有 2 个或更多事件侦听器的旧行,这些事件侦听器性能不佳并可能导致问题。

    一种解决方案是添加具有new-row 类的新行,然后将事件侦听器添加到new-rows,然后删除new-row id。

    JSFiddle:https://jsfiddle.net/rcf4qp85/

      $(function() {
        $('.event').on("dragstart", function(event) {
          var dt = event.originalEvent.dataTransfer;
          dt.setData('Text', $(this).attr('id'));
        });
        initnewrows();
        $('#addRow').on('click', function() {
          $('#targetTable > tbody:last-child').append('<tr class="new-row"><td></td><td></td><td></td></tr>'); initnewrows();
        });
      });
    
    function initnewrows() {
        $('table tr.new-row td').on("dragenter dragover drop", function(event) {
          event.preventDefault();
          if (event.type === 'drop') {
            var data = event.originalEvent.dataTransfer.getData('Text', $(this).attr('id'));
            de = $('#' + data).detach();
            de.appendTo($(this));
          }
        });
       $('table tr.new-row').removeClass('new-row');
    }
    

    您还必须将new-row 类添加到最初存在的trs

      <table id="targetTable" border="1">
        <thead>
          <tr class="new-row">
            <th>Col 1</th>
            <th>Col 2</th>
            <th>Col 3</th>
          </tr>
        </thead>
        <tbody>
          <tr class="new-row">
            <td><span class="event" id="a" draggable="true">Move Me</span></td>
            <td></td>
            <td></td>
          </tr>
          <tr class="new-row">
            <td></td>
            <td></td>
            <td></td>
          </tr>
        </tbody>
      </table>
    
      <p><button id='addRow'>Add Row</button></p>
      <p>
      You can successfully drag the "Move Me" block to any cell in the first two rows.<br/>But add a new row with the "Add Row" button, and you can't drop that block into any new row.
      </p>
    

    JSFiddle:https://jsfiddle.net/rcf4qp85/

    【讨论】:

    • 谢谢你,saintvixalien!你的解释帮助很大。我错过的主要问题是添加事件侦听器的时机。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多