LoginSignup
124
111

More than 3 years have passed since last update.

Javascript でドラック&ドロップを実装 (ライブラリ使わない)

Last updated at Posted at 2018-07-23

はじめに

Javascript でドラックアンドドロップを実装してみます。
全体の流れは以下です。
1. 移動させたい要素のpositionをabsoluteにする
2. マウスが移動するイベントを受け取り、移動させたい要素の(x,y)をマウスポインタの(x,y)と同じにする
3. マウスが離れたとき、ある矩形にマウスポインタが入ってるかどうか判定。

実装

クリックに対応させる

まずはマウスがクリックされたイベントを受け取りましょう。
簡単なhtml を書いてimgタグで画像を表示させます。
次にjavascriptでマウスクリックに対応させます。
htmlの要素がマウスクリックされると、onmousedownイベントが呼ばれます。
javascriptでonmousedownイベントをフックして、コンソールに文字列を表示させます。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>balltest</title>
</head>
<body>
  <div id="app">
    <img src="ball.png" id="ball" width="80px">
  </div>
  <script>
    var ball = document.getElementById("ball");
    ball.onmousedown = function(event){
      console.log("タップされたよ!");
    }
  </script>
</body>
</html>

画像がマウスの位置についてくる

次に、マウスが移動するイベントをフックします。
画像の位置を自由自在に操れるようにしたいので、positionをabsoluteにしておきます。

ball.style.position = "absolute";

ondragstartイベントはドラッグ操作を開始したときに呼ばれます。
ですが今回はmousemoveイベントを使って実装するのはこれは不要です。

ball.ondragstart = function(event){
  return false;
}

マウスが移動したときに、それと同じ位置に画像を配置します。
マウスポインタの(x,y)と、画像の(x,y)が同期するイメージです。
clientX は、ブラウザ画面の左端からの距離を取得します。
clientY はブラウザ画面の上端からの距離を取得します。
offsetWidth, offsetHeight では要素のサイズが取得できます。
これらの組み合わせて、マウスポインタの位置と画像の位置を同じにしましょう。
マウスポインタがすこしでも移動したとき(mousemoveイベント)にこれを登録します。

ball.onmousedown = function(event){
  document.addEventListener("mousemove",onMouseMove);
}
var onMouseMove = function(event){
  var x = event.clientX;
  var y = event.clientY;
  var width = ball.offsetWidth;
  var height = ball.offsetHeight;
  ball.style.top = (y-height/2) + "px";
  ball.style.left = (x-width/2) + "px";
}

ドロップで画像を削除

ある矩形内でマウスが離されたときに画像を削除する処理を追加します。
今回はいらすと屋からゴミ箱の画像を借りてきました。
マウスが離された時(onmouseupイベントが呼ばれた時)にやるべきことは2つです。

  • 画像がマウスポインタにひっついてくるイベントを解除
  • マウスポインタがゴミ箱の矩形内に存在するか判定する。trueならばボールを削除、falseならば何もしない
<img src="gomibako.png" id="gomibako" width="150px"><br>

(省略)

ball.onmouseup = function(event){
  var x = event.clientX;
  var y = event.clientY;
  var width = ball.offsetWidth;
  var height = ball.offsetHeight;
  var gomibakoRect = gomibako.getBoundingClientRect();
  if((x>=gomibakoRect.left && x<=(gomibakoRect.left+gomibakoRect.width)) && (y>=gomibakoRect.top && y<=(gomibakoRect.top+gomibakoRect.height))){
    var app = document.getElementById("app");
    app.removeChild(ball);
  }
  document.removeEventListener("mousemove",onMouseMove);
}

以上、こんな感じでドラックアンドドロップが実装できました!

まとめ

javascriptでドラックアンドドロップを実装するには・・・

  • 要素のpositionをabsolute にする
  • mousemove、mousedown、mousemoveイベントハンドラを上手に使う

デモはこちらから試せます。
以上です。

124
111
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
124
111