WEBサイトの製作、管理、とかの日記ブログです。

<<   2023年06月   >>
SunMonTueWedThuFriSat
    123
45678910
11121314151617
18192021222324
252627282930 
新着記事
カテゴリ
過去ログ
コメント
検索
mouseoverでmouseleaveの代用は簡単だった
コンテキストメニュー的なUIの作成で、サブメニュー部分をまずmouseenterとmouseleaveで作って、mouseleaveに非対応のブラウザ用にmouseoutでの処理を作ったんだが、mouseoutでmouseleaveの代用は思いのほか簡単だった。

まずコンテキストメニュー的なUIだが、
サブメニューの存在する項目にマウスオーバーしたらサブメニューを表示してマウスが外れたら非表示にするが、
サブメニューは基本的に項目の右に表示するが、項目からマウスが外れた際に移動先がサブメニュー上なら非表示にはしない必要がある。
つまり、項目からマウスが上下左に外れた場合はサブメニューを非表示にするが、右のサブメニュー方向に外れた場合は表示したままに。
というわけで、サブメニューを項目の子要素にしていればmouseleaveで簡単につくれるが、mouseoutでの代用は難しい。と思ったんだが、

element.addEventListener('mouseleave',function(e){
  非表示化処理
},false);
を、
element.addEventListener('mouseout',function(e){
  if(element.contains(e.relatedTarget)) return;
  非表示化処理
},false);
とrelatedTargetが子孫に含まれる場合は処理をキャンセルするだけで簡単に代用できた。

mouseoutイベント発生時は既にマウスが要素から出ていることになるが、e.targetは出た後の移動先要素ではなく出る前の要素になる。
relatedTargetは出た後の移動先要素となる。
だから、containsでrelatedTargetが子孫かどうか確認して、子孫なら処理をキャンセルすればmouseleaveと同じわけだね。

子要素に移動した場合は既に見た目上親要素から右にはみ出しているわけだが、子要素からさらにはみ出した場合にまた親要素でmouseoutは発生してくれる。

mouseenterの代わりにmouseoverにする部分も複数回発生することになるが、
今回の場合は座標に変化もないので複数回処理しちゃっ手も見た目に変化はないので単にmouseenterをmouseoverに変更するだけ。

この記事へのコメント
名前:
URL
コメント:
この記事へのトラックバック :
whblog 1.7