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 も貼っておきます。