TL;DR: 対象要素ではなく、documentにマウスイベントリスナを設定する
HTMLの要素をドラッグできるようにするときに、ウィンドウ外にドラッグされるとマウスイベントが受け取れなくてドラッグしっぱなしになってしまうとか、お絵かきで線を引きっぱなしになってしまうという悲しいことがよくあった。
たまたまjQueryUIのsortableを使ってみたところウィンドウ外でもドラッグできているので、どうやっているのかソースを見てみた。その名のui/widgets/sortable.jsではやってなくて、mouse.jsで、対象の要素や親じゃなくてdocumentにmousemoveとmouseupのイベントリスナを登録している。
ということなので、jQueryを使わないで素のJSでdocument.addEventListener()を使ってテストしたところ望み通りに動いた(デモとソース)。
windowにマウスイベントリスナを設定しても同様に受け取れた- FireFoxだとsetCapture()でキャプチャできる、が他のブラウザでは未実装…
- addEventListenerの第3引数の
useCaptureというのは今回の用途とは関係なくて、イベントをキャプチャフェーズで呼び出すかどうか、ということだった - Plnkrの編集画面や埋め込みのように
iframe内で動かされるとその外にマウスが出てしまうとイベントは取れない模様。- その場合には
mouseleaveを受け取ったら解除してやるとよい
- その場合には