Liste pratique réorganisable par glisser-déposer
Créez une liste réorganisable avec l’API de glisser-déposer.
Liste pratique réorganisable par glisser-déposer est une leçon HTML Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage HTML Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours HTML Academy comprend 4 leçons au total.
Vue d'ensemble du modèle
Pour créer une liste dont les éléments peuvent être réordonnés par glissement, rendez chaque élément déplaçable, stockez l'identifiant de l'élément déplacé dans dataTransfer lors de dragstart, puis, lors du dépôt, insérez l'élément déplacé avant ou après la cible. Le DOM et le modèle restent synchronisés si vous reconstruisez l'ordre à partir du DOM après chaque dépôt.
Balisage
Affichez une liste plate dans laquelle chaque li possède draggable="true" et un data-id. Conserver les identifiants sur les éléments signifie que les gestionnaires de glissement n'ont pas besoin d'interroger un magasin d'état distinct pour identifier les éléments : l'élément lui-même fait foi.
<ul id="list">
<li draggable="true" data-id="1">Item 1</li>
<li draggable="true" data-id="2">Item 2</li>
<li draggable="true" data-id="3">Item 3</li>
</ul>dragstart Enregistre la source
Lors de dragstart, stockez l'identifiant déplacé dans dataTransfer et appliquez une classe "dragging" pour fournir un retour visuel. effectAllowed="move" indique au navigateur qu'il s'agit d'un réordonnancement plutôt que d'une copie, de sorte que le curseur et dropEffect reflètent une opération de déplacement.
list.addEventListener("dragstart", (e) => {
const li = e.target.closest("li");
if (!li) return;
e.dataTransfer.setData("text/plain", li.dataset.id);
e.dataTransfer.effectAllowed = "move";
li.classList.add("dragging");
});dragover Autorise le dépôt
Écoutez les événements sur la liste (délégation d'événements), appelez preventDefault et définissez dropEffect sur "move". Utilisez e.target.closest("li") pour trouver la ligne survolée afin que le même gestionnaire fonctionne pour toute la liste.
Calcul de la position d'insertion
Pour décider si l'élément déplacé doit se placer au-dessus ou au-dessous de la ligne survolée, comparez la coordonnée Y du curseur au milieu vertical de la ligne : const before = (e.clientY - rect.top) < rect.height / 2. before=true signifie qu'il faut utiliser insertBefore, tandis que before=false signifie qu'il faut utiliser insertAfter.
function getInsertBefore(target, clientY) {
const rect = target.getBoundingClientRect();
return clientY < rect.top + rect.height / 2;
}drop Réordonne le DOM
Dans le gestionnaire drop, recherchez l'élément déplacé à partir de son identifiant ainsi que la ligne cible située sous le curseur. Appelez list.insertBefore(dragged, target) ou list.insertBefore(dragged, target.nextSibling) selon la moitié de la cible qui était survolée.
dragend Nettoie les styles
Que le dépôt réussisse ou que l'utilisateur appuie sur Échap, dragend est toujours déclenché sur la source. Utilisez-le pour supprimer la classe "dragging" et tous les surlignages de cible de dépôt afin que la liste retrouve son état au repos.
list.addEventListener("dragend", () => {
list.querySelectorAll(".dragging, .over").forEach((el) => {
el.classList.remove("dragging", "over");
});
});Indicateur visuel de dépôt
Affichez une ligne fine à l'endroit où l'élément sera placé à l'aide d'un pseudo-élément CSS sur la ligne survolée, activé par une classe "over-top" ou "over-bottom" que le gestionnaire dragover définit selon la position du curseur. L'utilisateur voit le point d'insertion avant de relâcher le bouton.
Synchronisation du modèle
Après le dépôt, déduisez le nouvel ordre à partir du DOM : const order = Array.from(list.children).map((li) => li.dataset.id). Envoyez ce tableau au serveur ou stockez-le dans l'état : n'essayez jamais de conserver un index parallèle au DOM, car il se désynchronise lors de glissements rapides.
Alternative au clavier
Ajoutez des gestionnaires Up/Down qui déplacent l'élément sélectionné avec insertBefore. Annoncez le déplacement via une région aria-live ("Élément déplacé vers le haut, en position 2"). Les utilisateurs du clavier bénéficient ainsi de la même fonctionnalité sans utiliser le glissement visuel, ce qui est essentiel pour l'accessibilité.
Solution de repli adaptée au tactile
Sur mobile, remplacez le glissement natif par les Pointer Events : lors de pointerdown, capturez la ligne ; lors de pointermove, déplacez-la avec la propriété CSS transform ; lors de pointerup, testez la ligne sous-jacente et réordonnez les éléments. Des bibliothèques comme SortableJS encapsulent ce modèle pour différents types d'entrée.
Vérification des connaissances
Pourquoi calculons-nous la position d'insertion à partir de la position du curseur par rapport au milieu vertical de la ligne survolée ?
Résumé
Une liste robuste permettant le réordonnancement associe draggable="true" + dragstart (enregistrement de l'identifiant, effectAllowed=move) + dragover (preventDefault + position de l'indicateur) + drop (insertBefore à l'emplacement déterminé par le milieu) + dragend (nettoyage). Déduisez toujours le nouvel ordre à partir du DOM après le dépôt et fournissez une solution de repli au clavier pour l'accessibilité.
Questions Fréquemment Posées
La leçon « Liste pratique réorganisable par glisser-déposer » est-elle gratuite ?
Oui — le texte complet de « Liste pratique réorganisable par glisser-déposer » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours HTML Academy, passe à CoddyKit PRO. Le cours HTML Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Liste pratique réorganisable par glisser-déposer » ?
Créez une liste réorganisable avec l’API de glisser-déposer. Tu pratiques HTML Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer HTML Academy ?
Aucune expérience préalable n'est requise. HTML Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Liste pratique réorganisable par glisser-déposer » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon HTML Academy ?
Oui. Chaque leçon HTML Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Attribut `draggable` et événement `dragstart`
- Événements `dragover` et `drop`
- Objet `dataTransfer`
- Liste pratique réorganisable par glisser-déposer