HTML要素をドラッグアンドドロップ(D&D)中にブラウザ外に出た場合、D&Dを終了するよう RxJS 5 を用いて実装する
HTML要素をドラッグアンドドロップ(以降 D&D)で移動させようと思ったときは、
対象要素に対する mousedown
、mousemove
、mouseup
のイベントを使って実装するかと思います。
しかしながらウィンドウ外では対象要素の mouseup
を捕捉できないため、
単純な実装ではウィンドウ外でD&Dをやめて戻った際、再度クリックなどしてmouseup
が発生するまで要素が追従してしまいます。
本記事では以下の挙動を RxJS で実装してみた例です。
- D&D 終了時は初期位置に移動する
- ウィンドウ外で D&D 終了(
mouseup
)を検知する
とりあえず触ってみてください。Google Chrome 57.0.2987.133 (64-bit) でしか動作確認してません。
「RxJS」初心者入門 – JavaScriptの非同期処理の常識を変えるライブラリ
にあるコードとほぼ同じですが、終了条件のストリームを mouseup
だけでなく $(window)
の mouseup
からも作っています。
// 終了条件を表すストリーム
var terminateDndStream = Rx.Observable.merge(
mouseUpStream,
Rx.Observable.fromEvent($(window), 'mouseup')
);
今回用いた技術的なポイントは以下の通りです。
window
内でドラッグを開始した場合、ウィンドウ外でのmouseup
やmousemove
を捕捉できる- イベントストリームをマージして OR 条件を表現する
参考:
- 「RxJS」初心者入門 – JavaScriptの非同期処理の常識を変えるライブラリ
- マウスをウィンドウ外で離されてもイベントを受け取る
- How to detect a MouseUp event outside the window?
Gist も貼っておきます。