イベント処理( 4 )
最終更新日:

前へ 目次 次へ

 今回も前回に引続きマウスイベントに関する食えない事情です。


 前回は、「IE のイベント通知の仕組みはヘン」という話でした。 では、 onmousedown/up についてはどうでしょう?

 onmousedown/up はドラッグ処理を行う場合によく使用します。
例えば、レイア( div )に対してイベント処理関数( rep )を登録する場合 以下のようにします。

◆NN の場合
div.document.onmousedown = rep;
div.document.onmouseup   = rep;
div.document.captureEvents(Event.MOUSEDOWN|Event.MOUSEUP);


◆IE の場合
div.onmousedown = rep;
div.onmouseup   = rep;
ドラッグ処理は通常 onmousemove も合わせて
使用しますが、ここでは省略しています。

 とりあえず、作成したレイア上でマウスボタンの「押す」「離す」をすると、 それぞれの操作時に rep 関数が呼出されることがわかります。
( rep が呼出されたかどうかは rep の処理としてTEXTAREA にでもイベント オブジェクトの type プロパティを出力するようにすれば確認できます )

 では、レイア上でマウスボタンを押し、レイア外にマウスを移動させて、 ボタンを離すとどうなるでしょうか。

◆NN の場合
onmousedown ---- ○( 呼出される )
onmouseup   ---- ○
◆IE の場合
onmousedown ---- ○
onmouseup   ---- ×( 呼出されない )

これは、NN がマウスボタンを押してから離すまでマウスイベントをグラブ ( 占有の意。 Windows風の表現ならキャプチャ )しているが、 IE では何もしていないのでレイア外のイベントが通知されないためです。

補足1
少なくとも NN4.6 では CaptureEvents を使用しなくても
グラブされます( なぜ? )。

補足2
何故か onmouseout イベントは IE でもグラブされます
( なぜ? 本当は move/up のつもりだったんじゃ.... )。

つまり IE でドラッグ操作を行うような処理を対象とするレイアにイベント処理を 登録して作成しようとすると、マウス操作に追いつかない状況が発生した場合には、 イベント通知されなくなり、ドラッグ処理が中断してしまう可能性が出て来ます。

これを回避するには document 自体にイベントハンドラを登録し、 ハンドラでどのレイア上でのマウス操作かを解析する必要がありますが、
これはすご〜く面倒です・・・・・・特にパフォーマンスを気にすると... f(^^;

そこでマウスボタンを離す( 移動する )場合の問題であることに注目して、

div.onmousedown    = dragStart;
document.onmouseup = dragEnd;

と言う具合に非対称な登録をすると解析の手間が減ります。 例えば


grabObject = null;  // グラブ中のオブジェクト
function dragStart(){
  // 操作されたレイアを登録
  grabObject = window.event.srcElement;
      :
  // グラブ中のオブジェクトに対する開始処理
      :
}
function dragEnd(){
  // 誰も登録してなければ無処理
  if(grabObject == null) return;
      :
  // グラブ中のオブジェクトに対する終了処理
      :
  grabObject = null; // グラブ中のオブジェクトをリセット
}
やはり onmousemove の処理は省略していますが、
基本的には dragEndと同様の処理をします。

この例ではグラブ対象のオブジェクトを
event.srcElement としていますが、実際には対象
のオブジェクトの探索をする必要があります。
( 前回の記事参照 )

この手法を用いてもウィンドウ外にマウスを移動
されるとそこで処理が中断するので、 ひと工夫
必要です。

ってなとこでしょうか。( ちょっと、安易に書きすぎたかなぁ... )


本当は「イベント処理」の項目は、「イベント概要」「マウス」「キー」の 3分割のつもりだったんだけど、未だに終わらない〜 f(^^;;;

前へ 目次 次へ


Copyright(c) 1999 ShinSoftAll rights reserved.