[jQuery]「特定要素以外をクリック」を取得

Googleのアカウント部分みたいなのを作ることができる

求める動作

  1. 特定の箇所をクリックしたらポップアップが表示される
  2. 特定の箇所をもう一度クリックしたらポップアップが非表示になる
  3. ポップアップ以外をクリックしたらポップアップが非表示になる
  4. ポップアップをクリックしてもポップアップは非表示にならない
  5. ポップアップの内部コンテンツ(aタグとか)は機能する

こんな感じ。

Google各種の右上にある、アカウントのやつとかをイメージすればいい感じ。

難点というかポイント

jsなりjQueryをきちんと理解してたらいいんだろうけど、全画面に背景つけたポップアップとかmouseover限定のポップアップとは全く違うんで、にわかには混乱するエグさがある。

ポップアップ以外をクリックした場合」が発火条件であり、ついでに「ポップアップが表示されている時」であり、「ポップアップ自体をクリックした場合を除外」なのでめちゃんこしんどい。

しかもまあ、今更ながら、ifは.on()の中で書かないと動作しないんで、今回のは主語がでかい内容になってしまう。あんまり好きじゃない。

組む

<span id="btn_popup">POPUP</span>
<div id="popup">
<ul>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
</div>

こんな感じのがあったとする。

CSSは割愛して、jsの方をやっていく。

$(document).on('click',function(e){
    if($(e.target).closest('#btn_popup').length){
        $('#popup).toggleClass('active');
        $('#popup').fadeToggle();
    }else if($(e.target).closest('#popup').length){
    }else{
        if($('#popup').hasClass('active')){
            $('#popup').fadeOut();
            e.preventDefault();
        }
    }
})

こうなる。完成させたら大したことなかったなーって感じではある。

ネックになるのは、ifで3パターンに分けなきゃいけないっていうところ。ポップアップ以外をクリックしたときに非表示にするのはelseで書いてあるとおりだけど、クリックしたのがaタグだったりしたらそれが起動して画面遷移しちゃう。それは不便だと思う。Googleもそこは遷移させずに非表示するようにしてる。

で、それだとポップアップ上をクリックしても消えるだけで意味がないんで、ポップアップ上をクリックしてもなんもないよっていうelse ifを追加する必要がある。

まあ、要するに以下の通りのif文になってるって話。

  1. #btn_popupを押したらポップアップが表示/非表示される
  2. ポップアップを押しても何もしない
  3. ポップアップ以外を押したらポップアップを非表示にする

以上。

まとめというか

普段は「これをクリックしたら」で作ってるけど、「クリックしたのがこれだったら」っていうアプローチになった。ひょっとしてこっちの書き方の方が楽だったりするんだろうか。

コメント

タイトルとURLをコピーしました