LoginSignup
8
7

More than 5 years have passed since last update.

jQueryでドラッグアンドドロップを実装する

Last updated at Posted at 2013-12-17

jQuery UI 使えば簡単にできるけど、カスタマイズしようとするとカオスになるので、自前でも実装できるようになっておきたい。

D&Dの仕様はいろいろあるけど、以下のようなものを考えてる。
これ、何気に難しいと思う。

  • ドラッグ時、掴んだ要素自体は動かさず、コピーを動かすこと
  • コピーの中心は、常にマウスの位置にあること
  • ドロップできる要素上をマウスホバーしたら、その要素をハイライトすること

実装手順

  1. ドラッグ対象要素のmousedownイベントを検知して、その要素のコピーを作る
  2. ドラッグ可能エリア (大抵はbodyとか) のmousemoveイベントを検知して、コピーの位置を変える
  3. ドロップできる要素のmouseenter mouseleaveイベントを検知して、ハイライトのオンオフを行う
  4. ドロップ出来る要素のmouseupイベントを検知して、ドロップ成功時の処理をする
  5. ドラッグ可能エリアのmouseupイベントを検知して、ドロップ失敗時の処理を行う

素直に考えるとこんな風な実装になると思うけど、問題点が1つある。
コピーを動かしている間は、ドロップ出来る要素のイベントを拾えない。

解決策1: display:none + document.elementFromPoint

document.elementFromPoint(x, y)は、x, yの位置に見えている要素を取得するメソッド。
コピーのmousemoveイベントは拾えるので、そのタイミングでマウス位置の要素を取得し、ホバーしてる要素を検出する。
しかし、単純にそのままdocument.elementFromPointしてもコピーしか取得できない。
そこで、コピーを一時的にdisplay: noneすることでコピーの裏側を取得できるようにする。

解決策2: pointer-event:none

pointer-eventを使えばHTML要素がマウス・タッチイベントにどう反応するのかを決めることができる。
noneにすると、イベントに反応しなくなる。

ブラウザが対応していれば、コピーに pointer-event: noneを指定してやるだけで問題は解決する。
しかし、まだ対応ブラウザが限られている。
特に、IEをサポートしなければならない場合使えない。

解決策3: インラインSVGを使う

HTML5では、HTML中にSVGタグを記述できるようになった。
IEでも、IE9以上のブラウザが対応している

実は、上記のpointer-eventsはSVG要素には使えるらしい。
らしい、というのはIE9が手元にないので確認できないため。

どなたか、この方法で動くかどうか確認してくだしあ><
http://jsfiddle.net/ectJu/1/

全然ダメでした!IE9どころかIE10でも動かない!

8
7
0

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