web-dev-qa-db-fra.com

Comment changer l'icône du curseur lors du glissement en HTML5?

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>
22
GibboK

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>
7
Ihsan

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

2
thenickname

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.

0
nikk wong

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();
}
0
mikiqex