即使阅读完所有这些答案后,我也为此付出了很多努力,并认为我可以与您分享我的解决方案,因为我认为这可能是较为简单的方法之一,尽管有些不同。我的想法是完全省略dragleave
事件侦听器,并在每个新的Dragenter事件被触发时对dragleave行为进行编码,同时确保不会不必要地触发Dragenter事件。
在下面的示例中,我有一个表,希望通过拖放API彼此交换表行内容。在上dragenter
,应将CSS类添加到您当前要将元素拖到其中的row元素上,以突出显示该元素,在上dragleave
,应删除该类。
例:
基本的HTML表格:
<table>
<tr>
<td draggable="true" class="table-cell">Hello</td>
</tr>
<tr>
<td draggable="true" clas="table-cell">There</td>
</tr>
</table>
和dragenter事件处理功能,添加到每个表格单元格(除了dragstart
,dragover
,drop
,和dragend
处理程序,这是不具体到这个问题,所以这里没有复制):
/*##############################################################################
## Dragenter Handler ##
##############################################################################*/
// When dragging over the text node of a table cell (the text in a table cell),
// while previously being over the table cell element, the dragleave event gets
// fired, which stops the highlighting of the currently dragged cell. To avoid
// this problem and any coding around to fight it, everything has been
// programmed with the dragenter event handler only; no more dragleave needed
// For the dragenter event, e.target corresponds to the element into which the
// drag enters. This fact has been used to program the code as follows:
var previousRow = null;
function handleDragEnter(e) {
// Assure that dragenter code is only executed when entering an element (and
// for example not when entering a text node)
if (e.target.nodeType === 1) {
// Get the currently entered row
let currentRow = this.closest('tr');
// Check if the currently entered row is different from the row entered via
// the last drag
if (previousRow !== null) {
if (currentRow !== previousRow) {
// If so, remove the class responsible for highlighting it via CSS from
// it
previousRow.className = "";
}
}
// Each time an HTML element is entered, add the class responsible for
// highlighting it via CSS onto its containing row (or onto itself, if row)
currentRow.className = "ready-for-drop";
// To know which row has been the last one entered when this function will
// be called again, assign the previousRow variable of the global scope onto
// the currentRow from this function run
previousRow = currentRow;
}
}
代码中保留了非常基本的注释,因此该代码也适合初学者。希望这对您有所帮助!请注意,您当然需要将我上面提到的所有事件侦听器添加到每个表单元格中,以使其工作。