こんにちは、HLCの掛橋です。
先日、とある機能を実装する際に、、、
※イメージ
オレンジ色の外側をクリックした時には外側のonClickメソッドを発火する
水色の内側をクリックした時には内側のonClickメソッドを発火する
という挙動をするように実装しようとしました。
何も考えずにただただ
<div onClick={()=>console.log('外側がクリックされました')} style={{backgroundColor:"orange",padding:"10px"}}> <p>外側</p> <button onClick={(event)=> {console.log('内側がクリックされました')}} style={{backgroundColor:"skyblue"}}> <p>内側</p> </button> </div>
と書いてみます。
外側クリック時には
うん、ええやん。
内側クリック時には
あれ!??
外側もクリックされたことになってるやん!
内側クリック時は、内側のonClickのみ発火させたいんやけどなぁ、、どうしよ。
ってことがありました。
失敗例:CSSで内側のzIndexを上に持っていったらいいんかな?
内側のボタンのCSSにzIndex:99999を付与。
<div onClick={()=>console.log('外側がクリックされました')} style={{backgroundColor:"orange",padding:"10px"}}> <p>外側</p> <button onClick={(event)=> {console.log('内側がクリックされました')}} style={{backgroundColor:"skyblue", zIndex:99999}}> <p>内側</p> </button> </div>
結果→ダメです。
浮かせたところで、下には外側が存在するんで外側のクリック判定はされるよね。。
成功例:eventのstopPropagation()メソッドを利用する
内側のonClick時にevent.stopPropagation()を実行させてみます。
<div onClick={()=>console.log('外側がクリックされました')} style={{backgroundColor:"orange",padding:"10px"}}> <p>外側</p> <button onClick={(event)=> {
console.log('内側がクリックされました')
event.stopPropagation()
}} style={{backgroundColor:"skyblue"}}> <p>内側</p> </button> </div>
結果
外側クリック時
内側クリック時
いけた!!!
どうやら
HTMLには小要素でイベントが発生すると、
親要素へイベントが伝搬(バブリング)していく挙動があるそうです。
今回使ったevent.stopPropagation()ではその伝搬を止めるメソッドになっています。
ためになったね〜