Salut,
Intéressant ! je prends.
Moi je ferais ainsi :
getBoundingClientRect() donne la position et les dimensions de l'élément cible, donc :
- Si la souris est dans la moitié haute ->
insertBefore(element, target)
- Si la souris est dans la moitié basse ->
insertBefore(element, target.nextSibling)
Pour connaître la position verticale de la souris dans l'élément, utiliser
e.clientY - rect.top.
Toutes ces classes CSS sur lesquelles le JavaScript s'appuie dans la démo... elles ne sont pas nécessaire : juste une classe sur les <ul> pour scoper les éléments draggables (ici
.drag-list) avec ce comportement spécifique sur la page et pour les items on s'appuie sur l'attribut natif
draggable="true", c'est tout.
Ça donne ceci :
CodePen
---
PS : j'ai enlevé les classes JS car c'est du sucre syntaxique en ECMAScript, verbeux et sous performant (j'exagère un peu).
PS du PS : le
window.addEventListener c'est parce que je suis sur CodePen, mais chez toi tu peux faire mieux en utilisant
DOMContentLoaded.
PS du PS du PS : je conseille de donner du feed-back pour les utilisateurs, sinon l'expérience n'est pas très agréable :
.drag-list {
&.drag-list-empty {
/* Hauteur minimale pour drop si liste vide : */
display: grid;
min-height: 3em;
width: 100%;
outline: .1em dashed #777;
&::before {
content: 'Glissez vos items';
align-content: center;
text-align: center;
}
}
li[draggable="true"] {
cursor: grab;
}
li[draggable="true"].dragged,
li[draggable="true"].over-top,
li[draggable="true"].over-bottom {
opacity: 0.4;
}
}
Édit : correction du JS qui accepte des items si parent
.drag-list vide, sinon on est bloqué.
Modifié par Olivier C (14 Jun 2026 - 10:26)