Подтвердить что ты не робот

Как изменить значок курсора при перетаскивании в HTML5?

Мне нужно установить значок для курсора, когда пользователь перетаскивает DIV (красный div в следующем примере).

Я пробовал несколько попыток, включая использование CSS cursor:move и event.dataTransfer.dropEffect без успеха, так как значок всегда показывает "скрещенный круг".

Любые идеи, как решить эту проблему, используя API перетаскивания 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>
4b9b3361

Ответ 1

использовать mousedown и 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>

Ответ 2

Добавление event.dataTransfer.setData(); должно решить проблему. Когда элемент распознается как перетаскиваемый, браузер автоматически добавит курсор перемещения после перетаскивания. Конечно, вам придется удалить все другие объявления cursor: move, чтобы увидеть, как меняется курсор при перетаскивании.

Минимальный пример:

document.getElementById('target').addEventListener('dragstart', function (event) {
  event.dataTransfer.setData( 'text/plain', '' );
}.bind(this));

Если вы все еще хотите изменить значок (например, для использования пользовательского значка перетаскивания), вы можете получить доступ к стилю элемента с помощью event.target.style.cursor.

Подробнее см. MDN Drag and Drop и MDN Рекомендуемые типы перетаскивания

Ответ 3

Вам действительно нужен Drag API? Я обнаружил, что использую Drag API, потому что у меня возникли проблемы с надежностью событий мыши (mouseups не mouseups мышиные mouseups).

API-интерфейс Drag предназначен только для функций перетаскивания, и, если вы просто играете с надежностью событий щелчка и наведения, новый API .setPointerCapture создан для более эффективной обработки этих случаев. Вот минимальный жизнеспособный способ добиться этого:

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)
}

Красиво, вы будете поддерживать полный контроль над стилем отображения курсора.

Ответ 4

Меня не волновал конкретный курсор, я просто хотел избавиться от "перечеркнутого круга". Мое решение состояло в том, чтобы включить событие dragover (со следующей функцией) во все элементы, которые уже имели события dragenter, dragstart и dragend.

function dragover(event)
{
    event.dataTransfer.dropEffect = "move";
    event.preventDefault();
}

Ответ 5

Посмотрите на события dragstart и dragend. myDragElm - это элемент, который перетаскивается.

EventUtil.addHandler(myDragElm, 'dragstart', function(e) {
    e.dataTransfer.setData(format, 'Dragme');
    e.dataTransfer.effectAllowed = effect;
    var target = EventUtil.getCurrentTarget(e);
    target.style.backgroundColor = 'green';
  // You can do this.Also you can use a css class to do this.
    target.style.cursor = 'move'; 
    return true;
});