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
を受け取ったら解除してやるとよい
- その場合には