javascript - 如何在具有动态添加的行和单元格的表格中拖放单元格内容?

标签 javascript html jquery drag-and-drop

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

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

这段近六年前的对话很接近我想做的事情。但它无法处理表中有动态添加的行的情况。 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/

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

如何克服这个限制?我很乐意使用 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/

最佳答案

问题是,当您添加 "dragenter Dragover drop" 事件监听器时,只有 2 行,这意味着对于添加的每个新行,您都必须添加事件监听器到它。

警告:如果每次添加新行时都运行事件监听过程,则最终旧行将具有 2 个或更多事件监听器,而这些事件监听器的性能不高,可能会导致问题。

解决方案是使用 new-row 类添加新行,然后将事件监听器添加到 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/

关于javascript - 如何在具有动态添加的行和单元格的表格中拖放单元格内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61492659/

相关文章:

jquery - jQMobile 对 jQuery 的依赖程度如何?

javascript - 使用 JQuery 添加几个 DIV

javascript - 两个数组的求和\相加(特别)

javascript - 带 Angular Bootstrap "Error: $(...).collapse() is not a function"

javascript - AngularJS 在 SVG 常量中设置填充颜色

html - css 问题中的简单导航栏,可能是一个非常简单的答案

javascript - 恒定高度 div 后跟占据所有空间的 div

javascript - 处理多个文件上传 : When you push something to an array, 数组何时更新?

javascript - 我想为每个滚动CSS更改文本

html - 大部分内容都在 body 之外