J'ai beaucoup lutté avec cela, même après avoir lu toutes ces réponses, et j'ai pensé que je pourrais partager ma solution avec vous, parce que je pensais que ce pourrait être l'une des approches les plus simples, quelque peu différente cependant. Ma pensée était simplement d'omettre dragleave
complètement l'écouteur d'événements et de coder le comportement de glisser-déplacer avec chaque nouvel événement dragenter déclenché, tout en s'assurant que les événements dragenter ne soient pas déclenchés inutilement.
Dans mon exemple ci-dessous, j'ai une table, où je veux pouvoir échanger le contenu des lignes de table entre elles via l'API glisser-déposer. Le dragenter
, une classe CSS doit être ajoutée à l'élément de ligne dans lequel vous faites actuellement glisser votre élément, pour le mettre en surbrillance, et sur dragleave
, cette classe doit être supprimée.
Exemple:
Tableau HTML très basique:
<table>
<tr>
<td draggable="true" class="table-cell">Hello</td>
</tr>
<tr>
<td draggable="true" clas="table-cell">There</td>
</tr>
</table>
Et la fonction de gestionnaire d'événements dragenter, a ajouté sur chaque cellule de table ( à part dragstart
, dragover
, drop
et les dragend
gestionnaires qui ne sont pas spécifiques à cette question, donc pas copiés ici):
/*##############################################################################
## 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;
}
}
Commentaires très basiques laissés dans le code, tels que ce code convient aussi aux débutants. Espérons que cela va vous aider! Notez que vous devrez bien sûr ajouter tous les écouteurs d'événement que j'ai mentionnés ci-dessus sur chaque cellule du tableau pour que cela fonctionne.