概要
Ruby on Railsでアプリケーションを作成中、jQueryでプルダウンを作成することに。
プルダウンメニューには
link_to ~~_path, method: :delete
というログアウト用のリンクを設定。
プルダウンも無事実装し、めでたしめでたし・・・ん?
リンクで飛ぶと Routing Erorrが発生するぞ?
method: :delete
で 指定しているはずなのに、何故かDELETEに飛ばずにGETに飛ぶ現象に
問題のコード
$(function(){
$('.クラス名').on('click',function(e){
$(this).children('.クラス名').slideToggle();
e.stopPropagation();
});
$(document).on('click', function() {
$('.クラス名').hide();
});
$('.クラス名').click(function(e) {
e.stopPropagation();});
});
原因
プルダウンを作ったjQueryのe.stopPropagation
メソッドが悪さをしていた。
解説
link_to method: :delete
は aタグに変換された時にdata-method="delete"
の形になる。
この形で実際に行われる挙動はjavascriptが担っており、階層としてはdocumentにイベントを仕掛けている。
e.stopPropagation
メソッドは親階層への伝播をとめるメソッド
ここでは、プルダウンを開くために押した先に要素より親の階層へのイベントの伝播がしなくなっている状態。
結果としてdocumentに仕掛けているdata-method="delete"
までクリックしてもイベントが届かない。
つまりdeleteが無効化されてデフォルトのGETで リンクを飛ばしている、ということになっている。
何をしたか
e.stopPropagation();
を使いつつ解決する方法が分からなかった。
ということで、documentを何処でもクリックしたらプルダウンを閉じる、
という記述にプルダウンとプルダウンメニューを押したときだけは閉じない、というif文を加えた。
修正したコード
$(function(){
$('.クラス名').on('click',function(e){
$(this).children('.クラス名').show();
});
$(document).on('click', function(e) {
if (!$(e.target).closest('.クラス名').length){
$('.クラス名').fadeOut();
}
});
});