Je dois définir l'icône du curseur lorsqu'un utilisateur fait glisser DIV (div rouge dans l'exemple suivant).
J'ai essayé plusieurs fois, notamment en utilisant CSS cursor:move
et event.dataTransfer.dropEffect
sans succès, car l'icône affiche toujours un "cercle croisé".
Avez-vous des idées sur la façon de résoudre ce problème à l'aide de l'API glisser-déposer HTML5?
http://jsbin.com/hifidunuqa/1/
<script>
window.app = {
config: {
canDrag: false,
cursorOffsetX: null,
cursorOffsetY: null
},
reset: function () {
this.config.cursorOffsetX = null;
this.config.cursorOffsetY = null;
},
start: function () {
document.getElementById('target').addEventListener('dragstart', function (event) {
console.log('+++++++++++++ dragstart')
this.config.cursorOffsetX = event.offsetX;
this.config.cursorOffsetY = event.offsetY;
this.adjustPostion(event);
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.dropEffect = 'move';
}.bind(this));
document.getElementById('target').addEventListener('drag', function (event) {
console.log('+++++++++++++ drag')
this.adjustPostion(event);
}.bind(this));
document.getElementById('target').addEventListener('dragend', function (event) {
console.log('+++++++++++++ dragend')
this.reset();
}.bind(this));;
},
adjustPostion: function (event) {
if (event.pageX <= 0 || event.pageY <= 0) {
console.log('skipped');
return;
}
var Elm = document.getElementById('target');
Elm.style.left = (event.pageX - this.config.cursorOffsetX) + 'px';
Elm.style.top = (event.pageY - this.config.cursorOffsetY) + 'px';
console.log(event.pageX);
console.log(event.pageY);
}
};
</script>
utiliser mousedown et mousemove
window.app = {
dragging: false,
config: {
canDrag: false,
cursorOffsetX: null,
cursorOffsetY: null
},
reset: function () {
this.config.cursorOffsetX = null;
this.config.cursorOffsetY = null;
},
start: function () {
document.getElementById('target').addEventListener('mousedown', function (event) {
console.log('+++++++++++++ dragstart');
this.dragging = true;
this.config.cursorOffsetX = event.offsetX;
this.config.cursorOffsetY = event.offsetY;
this.adjustPostion(event);
}.bind(this));
document.getElementById('target').addEventListener('mousemove', function (event) {
if (this.dragging) {
console.log('+++++++++++++ drag');
event.target.style.cursor = 'move';
this.adjustPostion(event);
}
}.bind(this));
document.getElementById('target').addEventListener('mouseup', function (event) {
console.log('+++++++++++++ dragend');
this.dragging = false;
event.target.style.cursor = 'pointer';
this.reset();
}.bind(this));
},
adjustPostion: function (event) {
if (event.clientX <= 0 || event.clientY <= 0) {
console.log('skipped');
return;
}
var Elm = document.getElementById('target');
Elm.style.left = (event.clientX - this.config.cursorOffsetX) + 'px';
Elm.style.top = (event.clientY - this.config.cursorOffsetY) + 'px';
console.log(event.pageX);
console.log(event.pageY);
}
};
#target {
position: absolute;
top: 100px;
left: 100px;
width: 400px;
height: 400px;
background-color: red;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
}
#ui1 {
position: absolute;
top: 50px;
left: 50px;
width: 100px;
height: 400px;
background-color: blue;
z-index: 100;
}
#ui2 {
position: absolute;
top: 50px;
left: 550px;
width: 100px;
height: 400px;
background-color: green;
z-index: 100;
}
<!-- simulate -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
</head>
<body onload="window.app.start();">
<div id="ui1"></div>
<div id="ui2"></div>
<div id="target"></div>
</body>
</html>
L'ajout de event.dataTransfer.setData();
devrait résoudre le problème. Une fois que l'élément est reconnu comme pouvant être déplacé, le navigateur ajoute automatiquement un curseur de déplacement une fois que vous faites glisser. Bien sûr, vous devrez supprimer tous les autres cursor: move
déclarations pour voir le curseur changer pendant le glissement.
Exemple minimal:
document.getElementById('target').addEventListener('dragstart', function (event) {
event.dataTransfer.setData( 'text/plain', '' );
}.bind(this));
Si vous souhaitez toujours modifier l'icône (par exemple, pour utiliser une icône de glissement personnalisée), vous pouvez accéder au style d'élément à l'aide de event.target.style.cursor
.
Pour plus d'informations, voir Glisser-déposer MDN et Types de glissement recommandés MDN
Avez-vous réellement besoin l'API Drag
? J'ai constaté que j'utilisais l'API Drag
parce que j'avais des problèmes avec la fiabilité des événements de souris (mouseups
n'étant pas capturé, par exemple).
L'API Drag
est uniquement destinée à la fonctionnalité de glisser-déposer et, si vous ne jouez qu'avec la fiabilité de vos événements de clic et de pointage, une nouvelle API, .setPointerCapture
est conçu pour gérer ces cas plus efficacement. Voici le moyen viable minimal d'y parvenir:
el.onpointerdown = ev => {
el.onpointermove = pointerMove
el.setPointerCapture(ev.pointerId)
}
pointerMove = ev => {
console.log('Dragged!')
}
el.onpointerUp = ev => {
el.onpointermove = null
el.releasePointerCapture(ev.pointerId)
}
Magnifiquement, vous garderez un contrôle total sur le style d'affichage de votre curseur.
Je ne me souciais pas d'un curseur en particulier, je voulais juste me débarrasser de celui du "cercle croisé". Ma solution était d'inclure dragover événement (avec la fonction suivante) à tous les éléments, qui avaient déjà des événements dragenter, dragstart et dragend.
function dragover(event)
{
event.dataTransfer.dropEffect = "move";
event.preventDefault();
}