如何在具有动态添加的行和单元格的 table 中拖放单元格内容?
How can I drag-and-drop cell contents within a table with dynamically added rows and cells?
我在使用动态生成的 table 进行拖放时遇到困难。该界面根据用户选择呈现 table 行和单元格的网格。
我想要做的是让用户能够将一个单元格(div 或跨度)的内容拖到另一个单元格中。
这段将近 6 年前的对话很接近我想做的事情。但它无法处理 table 具有动态添加的行的情况。
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/
您可以成功地将蓝色块拖放到前两行的任意单元格中。但是使用 "Add Row" 按钮添加一个新行,您不能将该块放入任何新行中。您仍然可以将可拖动范围移动到前两行中的不同单元格。但是拖入新行失败
如何克服这个限制?我很乐意使用 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));
}
});
}
问题是,当您添加 "dragenter dragover drop"
事件侦听器时,只有 2 行,这意味着对于添加的每个新行,您都必须向其添加事件侦听器。
注意:如果每次添加新行时都运行事件侦听过程,您最终会得到具有 2 个或更多事件侦听器的旧行这不是高性能的,可能会导致问题。
一种解决方案是添加 class 为 new-row
的新行,然后将事件侦听器添加到 new-row
,然后删除 new-row
ids.
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');
}
您还必须将 class 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/
我在使用动态生成的 table 进行拖放时遇到困难。该界面根据用户选择呈现 table 行和单元格的网格。
我想要做的是让用户能够将一个单元格(div 或跨度)的内容拖到另一个单元格中。
这段将近 6 年前的对话很接近我想做的事情。但它无法处理 table 具有动态添加的行的情况。 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/
您可以成功地将蓝色块拖放到前两行的任意单元格中。但是使用 "Add Row" 按钮添加一个新行,您不能将该块放入任何新行中。您仍然可以将可拖动范围移动到前两行中的不同单元格。但是拖入新行失败
如何克服这个限制?我很乐意使用 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));
}
});
}
问题是,当您添加 "dragenter dragover drop"
事件侦听器时,只有 2 行,这意味着对于添加的每个新行,您都必须向其添加事件侦听器。
注意:如果每次添加新行时都运行事件侦听过程,您最终会得到具有 2 个或更多事件侦听器的旧行这不是高性能的,可能会导致问题。
一种解决方案是添加 class 为 new-row
的新行,然后将事件侦听器添加到 new-row
,然后删除 new-row
ids.
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');
}
您还必须将 class 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/