J'ai une page HTML qui contient des éléments déplaçables. Nos spécifications indiquent qu'en pointant la souris sur cet élément, le curseur doit être grab
, et pendant que vous faites glisser le curseur doit être grabbing
.
Je sais qu'il est possible de définir dropEffect
qui modifie l'apparence du curseur au-dessus de la zone de dépôt, mais il existe très peu d'options: copy
, move
, link
et none
- no custom ou similaire.
J'ai essayé de changer le curseur avec Javascript et CSS, comme pour le paramètre cursor: grabbing;
quand ondragstart
est déclenché. Mais le curseur de déplacement par défaut du navigateur apparaît à la place lorsque vous faites glisser la zone de dépôt.
La question est donc la suivante:Que me manque-t-il pour afficher le curseur de saisie ( ) pendant le drag?
Malheureusement, je ne peux pas utiliser JQuery ou d'autres bibliothèques d'aide dans la solution. Merci d'avance!
var onDragStart = function(event) {
event.dataTransfer.setData("Text", event.target.id);
event.currentTarget.classList.add("being-dragged");
};
var onDragEnd = function(event) {
event.currentTarget.classList.remove("being-dragged");
};
var onDragOver = function(event) {
event.preventDefault();
};
.dropzone {
width: 500px;
height: 200px;
background-color: silver;
}
.block {
position: absolute;
background-color: pink;
margin: 10px;
border: 20px solid pink;
}
.draggable {
cursor: -webkit-grab;
cursor: grab;
}
.being-dragged {
cursor: -webkit-grabbing;
cursor: grabbing;
background-color: red;
}
<div class = "dropzone"
ondragover = "onDragOver(event);"
>
Grab and drag block around
<div class = "draggable block"
draggable = "true"
ondragstart = "onDragStart(event);"
ondragend = "onDragEnd(event);"
>
I'm draggable
</div>
</div>
Il semble que les navigateurs ne permettent pas de changer le curseur au début d’une opération de glisser-déposer. Je ne sais pas pourquoi mais c'est un problème connu, je pense qu'ils le seront à l'avenir.
Si jQuery n'est pas une option, vous pouvez implémenter un glisser-déposer à partir de zéro, en utilisant des événements de souris et en clonant l'élément source:
var onDragStart = function (event) {
event.preventDefault();
var clone = event.target.cloneNode(true);
clone.classList.add("dragging");
event.target.parentNode.appendChild(clone);
var style = getComputedStyle(clone);
clone.drag = {
x: (event.pageX||(event.clientX+document.body.scrollLeft)) - clone.offsetLeft + parseInt(style.marginLeft),
y: (event.pageY||(event.clientY+document.body.scrollTop)) - clone.offsetTop + parseInt(style.marginTop),
source: event.target
};
};
var onDragMove = function (event) {
if (!event.target.drag) {return;}
event.target.style.left = ((event.pageX||(event.clientX+document.body.scrollLeft)) - event.target.drag.x) + "px";
event.target.style.top = ((event.pageY||(event.clientY+document.body.scrollTop)) - event.target.drag.y) + "px";
};
var onDragEnd = function (event) {
if (!event.target.drag) {return;}
// Define persist true to let the source persist and drop the target, otherwise persist the target.
var persist = true;
if (persist || event.out) {
event.target.parentNode.removeChild(event.target);
} else {
event.target.parentNode.removeChild(event.target.drag.source);
}
event.target.classList.remove("dragging");
event.target.drag = null;
};
var onDragOver = function (event) {
event.preventDefault();
};
.dropzone {
width: 500px;
height: 200px;
background-color: silver;
}
.block {
position: absolute;
background-color: pink;
margin: 10px;
border: 20px solid pink;
}
.draggable {
position: absolute;
cursor: pointer; /* IE */
cursor: -webkit-grab;
cursor: grab;
}
.dragging {
cursor: -webkit-grabbing;
cursor: grabbing;
background-color: red;
}
<div class="dropzone" onmouseover="onDragOver(event);">
Grab and drag block around
<div class = "draggable block"
onmousedown = "onDragStart(event);"
onmousemove = "onDragMove(event);"
onmouseup = "onDragEnd(event);"
onmouseout = "event.out = true; onDragEnd(event);"
>
I'm draggable
</div>
</div>
C'est un problème connu rapporté ici
En glissant, le curseur se changera automatiquement en normal.
Mes essais m'ont donné le suivant. A donné une active
sur l'élément avec le curseur de saisie. Pendant qu'il est actif, le curseur changera mais une fois que vous aurez commencé le glissement, il changera automatiquement.
J'ai essayé de définir le curseur body
pour saisir sur dragstart mais aucun résultat. Même cela ne fonctionne pas.
var onDragStart = function(event) {
event.dataTransfer.setData("Text", event.target.id);
event.currentTarget.classList.add("being-dragged");
};
var onDragEnd = function(event) {
event.currentTarget.classList.remove("being-dragged");
};
var onDragOver = function(event) {
event.preventDefault();
};
.dropzone {
width: 500px;
height: 200px;
background-color: silver;
}
.block {
position: absolute;
background-color: pink;
margin: 10px;
border: 20px solid pink;
}
.draggable {
cursor: -webkit-grab;
cursor: grab;
}
.draggable:active{
cursor : -moz-grabbing;
cursor: -webkit-grabbing;
cursor: grabbing;
}
.being-dragged{
background-color: red;
cursor : -moz-grabbing;
cursor: -webkit-grabbing;
cursor: grabbing;
}
<div class = "dropzone"
ondragover = "onDragOver(event);"
>
Grab and drag block around
<div class = "draggable block"
draggable = "true"
ondragstart = "onDragStart(event);"
ondragend = "onDragEnd(event);"
>
I'm draggable
</div>
</div>
Essaye ça ! Ça marche pour moi !
.draggable {
cursor: -webkit-grab;
cursor: grab;
}
.draggable:active {
cursor: -webkit-grabbing;
cursor: grabbing;
}
Je connais juste un peu les éléments déplaçables avec JavaScript
pur et je suis désolé de ne pouvoir expliquer ce qui suit.
Le problème était que la onDragEnd
ne se faisait jamais virer. J'ai donc cherché quelque chose et trouvé ce exemple avec des éléments déplaçables.
Maintenant, si vous modifiez la fonction de l'événement onDragStart
, cela fonctionnera, mais je pense que vous devez modifier le curseur d'une autre manière, par exemple pour changer la classe du corps onDragStart
var onDragStart = function(event) {
event.dataTransfer.setData("Text", event.target.id);
event.currentTarget.classList.add("being-dragged");
};
Tout en un
var onDragStart = function(event) {
event.dataTransfer.setData("Text", event.target.id);
event.currentTarget.classList.add("being-dragged");
};
var onDragEnd = function(event) {
event.currentTarget.classList.remove("being-dragged");
};
var onDragOver = function(event) {
event.preventDefault();
};
.dropzone {
width: 500px;
height: 500px;
background-color: silver;
}
.block {
width: 200px;
height: 50px;
background-color: pink;
}
.draggable1 {
cursor: -webkit-grab;
cursor: grab;
}
.being-dragged {
cursor: -webkit-grabbing;
cursor: grabbing;
background-color: red;
}
<div class="dropzone" ondragover="onDragOver(event);">
<div class="draggable1 block" draggable="true" ondragstart="onDragStart(event);" ondragend="onDragEnd(event);">
I'm draggable
</div>
</div>
J’ai passé quelque temps à trouver une solution à cela, a terminé avec cette astuce. Je pense que c'est la meilleure façon moins de code et de travail.
.drag{
cursor: url('../images/grab.png'), auto;
}
.drag:active {
cursor: url('../images/grabbing.png'), auto;
}