如何实现简单的原生拖放?

时间:2017-09-18 15:06:23

标签: javascript drag-and-drop

我试图在div上实现简单的拖放效果。我使用的是原生HTML5 API。基本上,我试图将左侧粉红色框拖到深灰色区域。看到小提琴:一切似乎都没问题,但是,我无法将盒子放在深灰色区域。

https://jsfiddle.net/pablodarde/2wy1s2vn/

我使用此documentation作为支持。

这是我的代码:

HTML

<div class="container">
  <div class="side-bar">
    <div class="box" draggable='true'></div>
  </div>
  <div class="drop-zone"></div>
</div>

的JavaScript

const box = document.querySelector('.box');
const dropZone = document.querySelector('.drop-zone');

const handleDragStart = (e) => {
    console.log(e.dataTransfer);
  e.dataTransfer.effectAllowed = 'move';
};

const handleDragEnter = (e) => {
    e.target.className += ' active-drop';
  e.dataTransfer.dropEffect = 'move';
  console.log(e.dataTransfer);
  e.preventDefault();
  e.stopPropagation();
}

const handleDragLeave = (e) => {
  e.target.className = 'drop-zone';
}

const handleDrop = (e) => {
    console.log('Drop!!');
  e.preventDefault();
  e.stopPropagation();
}

box.addEventListener('dragstart', handleDragStart);

box.addEventListener('drop', handleDrop);

dropZone.addEventListener('dragenter', handleDragEnter);

dropZone.addEventListener('dragleave', handleDragLeave);

2 个答案:

答案 0 :(得分:1)

以下4项内容应解决您的浏览器/事件相关问题,并为您处理:

  1. 必须将public class MainMenuScreen implements Screen { final Drop game; OrthographicCamera camera; public MainMenuScreen(final Drop game) { this.game = game; camera = new OrthographicCamera(); camera.setToOrtho(false, 800, 480); } //...Rest of class omitted for succinctness. } 事件附加到drop div。
  2. 取消dropZone事件处理程序中的事件。你没有,添加它。
  3. 对于Firefox:

    1. 将以下行添加到dragover处理程序:

      dragstart
    2. 这可以是任何 键值 ,但必须设置拖放才能在Firefox中使用。我已经设置了盒子的ID,因为我想在drop handler中使用它。

      1. 删除处理以将框附加到dropzone:https://jsfiddle.net/kyqr1o6b/3/
      2. 丢弃处理的最终工作代码https://jsfiddle.net/kyqr1o6b/6/

        更新:添加了对Firefox的支持。

        更新2 :丢弃处理。

        更新3 :已捕获位置。

答案 1 :(得分:0)

虽然我接受了上述答案,但我在这里留下了React的选项。我发现了如何探索React状态功能以轻松构建简单的拖放解决方案

Codepen https://codepen.io/pablodarde/pen/gGoQYo

<强>的JavaScript

class Square extends React.Component {
  constructor() {
    super();
    this.state = {
      posx: 10,
      posy: 10,
    };
    this.setDrag = this.setDrag.bind(this);
    this.startDrag = this.startDrag.bind(this);
    this.stopDrag = this.stopDrag.bind(this);
  }

  componentDidMount() {
    this.sq.addEventListener('mousedown', this.setDrag);
  }

  startDrag(e) {
    console.log('posx: ', this.state.posx);
    console.log('startPosX: ', this.startPosX);
    this.setState({
      posx: parseInt(e.clientX - this.startPosX, 10),
      posy: parseInt(e.clientY - this.startPosY, 10),
    });
    this.startPosX = e.clientX - this.state.posx;
    this.startPosY = e.clientY - this.state.posy;
  }

  stopDrag() {
    document.documentElement.removeEventListener('mousemove', this.startDrag);
    document.documentElement.removeEventListener('mouseup', this.stopDrag);
    this.sq.addEventListener('mousedown', this.setDrag);
  }

  setDrag(e) {
    console.log('mouse down');
    this.sq.removeEventListener('mousedown', this.setDrag);
    this.startPosX = e.clientX - this.state.posx;
    this.startPosY = e.clientY - this.state.posy;
    document.documentElement.addEventListener('mousemove', this.startDrag);
    document.documentElement.addEventListener('mouseup', this.stopDrag);
  }

  render() {
    return (
      <div
        className='square'
        style={{
          left: this.state.posx,
          top: this.state.posy,
        }}
        ref={(sq) => { this.sq = sq; }}
      >
        {this.state.posx}
      </div>
    );
  }
}

ReactDOM.render(
  <Square />,
  document.getElementById('app')
);

<强> CSS

.square {
  position: absolute;
  width: 100px;
  height: 100px;
  background: #900;
  border: 1px solid #333;
}