HTML5のドラッグ&ドロップとはちょっと違う… HTMLの任意DOM要素同士でドラッグ&ドロップしたいんだよね。。 どのイベント使っていいかわからないから、とりあえず「前編」として調査です。
ブラウザ別イベントの発生順序
次のような状況(プログラム)を想定して、IE、Chr(Chrome)、FF(FireFox)において どのような順序でイベントが発生するか調査してみた。
- とりあえず、一通りのイベントをドラッグ対象となる任意のDOM要素(source)に追加。
- とりあえず、一通りのイベントをドロップ先となる任意のDOM要素(target)に追加。
- ドラッグ対象となる任意のDOM要素(source)を mousedown
- mousedown された 任意のDOM要素(source) のクローン(clone)を作成
- 作成したクローン(clone)を body 末尾へ追加
- 作成したクローン(clone)に style を追加
- 任意のDOM要素(source)に style を追加
- mousemove で 作成したクローン(clone)を移動
- ドロップ先となる任意のDOM要素(target)上で作成したクローン(clone)を mouseup
- 作成したクローン(clone)を body 末尾から削除
※上記シーケンスは若干適当に書かれているので、実際とは異なる部分があります。
調査結果
基本的な操作のとき(ゆっくり操作したとき)は、次の表のようなイベント順になる。 色をつけた行が「使えそうかな?」と思えるイベントとタイミング。 document.onmouseup の後、target.onmouseenter または target.onmouseover が発生すると、どこへドロップされたと見なせる。
| 実行シーケンス | DOM要素 | イベント | IE8 | IE9 | Ch23 | FF14 |
|---|---|---|---|---|---|---|
| 1 | source | mousedown | o | o | o | o |
| 2 | document | mousedown | o | o | o | o |
| 3 | source | mouseleave | o | o | o | o |
| 4 | source | mouseup | o | o | o | o |
| 5 | clone | mouseleave | o | |||
| 6 | clone | mouseup | o | |||
| 7 | document | mouseup | o | o | o | o |
| 8 | document | mousemove | o | o | ||
| 9 | source | mouseover | o | |||
| 10 | clone | mouseenter | o | o | o | |
| 11 | clone | mouseover | o | o | o | o |
| 12 | document | mouseover | o | o | o | o |
| 13 | document | mousemove | o | o | o | o |
| 14 | source | mouseup | o | |||
| 15 | clone | mouseup | o | o | o | o |
| 16 | document | mouseup | o | o | o | o |
| 17 | document | mousemove | o | o | ||
| 18 | clone | mouseleave | o | |||
| 19 | clone | mouseup | o | |||
| 20 | target | mouseenter | o | o | o | o |
| 21 | target | mouseover | o | o | o | o |
| 22 | document | mouseenter | o | o | ||
| 23 | document | mouseover | o | o | o | o |
| 24 | document | mousemove | o | o | o |
※IE = Internet Explorer、Ch = Chrome、FF = Firefox
マウス移動を素早く行うと、描画がが追いつかず、別のイベントが発生してしまう。 次の表にあげるいずれかが、ランダムに発生する。 IE8だけ、発生するタイミングが怪しいけど、発生するイベントの種類や数は似ている (というか、ランダム発生だから何ともいえない。)。
| 実行シーケンス | DOM要素 | イベント | IE8 | IE9 | Ch23 | FF14 |
|---|---|---|---|---|---|---|
| 1 | clone | mouseenter | o | o | o | o |
| 2 | clone | mouseover | o | o | o | o |
| 3 | clone | mouseleave | o | o | o | o |
| 4 | clone | mouseup | o | o | o | o |
※IE = Internet Explorer、Ch = Chrome、FF = Firefox
| 実行シーケンス | DOM要素 | イベント | IE8 | IE9 | Ch23 | FF14 |
|---|---|---|---|---|---|---|
| 1 | target | mouseenter | o | o | o | o |
| 2 | target | mouseover | o | o | o | o |
| 3 | target | mouseleave | o | o | o | o |
| 4 | target | mouseup | o | o | o | o |
※IE = Internet Explorer、Ch = Chrome、FF = Firefox
結局…
どいうイベントを監視、実装したら良さそうか?
- source.onmousedown:ドラッグ開始
- document.onmousemove:ドラッグ中のエフェクト
- document.onmouseup:ドラッグ終了。ドロップしたフラグ。
- ドロップしたフラグが立っているとき、
- target.onmouseenter または target.onmouseover:ドロップされた
- document.onmouseover:ドロップされなかった
- 後始末(イベントハンドラ、フラグ類)
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!
