- 締切済み
jQuery - bind('click', x)
<!DOCTYPE html> <script src="jquery-1.7.1.js"></script> <style> .menu_items { display: none; } </style> <script> $(function() { $('.dropdown').each(function () { var menu = $(this).parent().children('.menu_items'); var hideFunc = function() { menu.slideUp(120); $(document).unbind('click', hideFunc); }; $(this).click(function() { menu.slideDown(120); $(document).bind('click', hideFunc); }); }); }); </script> <div> <button class="dropdown">Currency</button> <ul class="menu_items"> <li><button>USD</button> <li><button>EUR</button> <li><button>GBP</button> </ul> </div> -- jquery でメニューに表示・非表示をしたいと思ってます。 click したあとに、メニューを消す命令を bind してるってのに、 この hideFunc (メニューを消す命令) がすぐ呼ばれてしまいます。 適当な配列をフラグに使って二回目呼ばれたときには消す、みたいな解決策を思い来ましたが、 いまいちスマートな感じがしません。 ちゃんとクリックが終わったあとに hideFunc をバインドしたいのですが、それはなにかいい書き方あれば教えてください
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- fujillin
- ベストアンサー率61% (1594/2576)
スライドアップをなぜドキュメントのクリックに設定しているのかわからないけれど、複数ある他のメニューを閉じようという意図でしょうか? とりあえず、同じボタンのクリックで開/閉するのならこんなのでは? $(function() { $('.dropdown').each(function(){ var menu = $(this).parent().children('.menu_items'); $(this).toggle( function(){ menu.slideDown(120); }, function(){ menu.slideUp(120); } ); }); }); ドキュメントにイベントを設定すると閉じてしまう理由は、このボタンのクリックイベント処理の後に(上位の)ドキュメントにクリックが伝播するからです。(詳しくは、「イベントバブル」などをキーに検索してください) どこをクリックしてもメニューを全部閉じたいということでしょうか? リンクをクリックしているかも知れないし、他のイベントのトリガーをクリックしているかも知れないので、ドキュメントのクリックに無条件に反応するというのもちょっと疑問ですが… それは置いておいて、ドキュメントのクリック側でボタン以外を押されたことを確認して閉じるか、またはイベントのバブル後にメニューを開くようにするとかすればよさそう。 前者であれば $(function() { $('.dropdown').each(function(){ var elm = this; var menu = $(this).parent().children('.menu_items'); $(this).click(function(){ menu.slideDown(120); }); $(document).click(function(e){ if(e.target != elm) menu.slideUp(120); }); }); }); 後者であれば $(function() { $('.dropdown').each(function(){ var menu = $(this).parent().children('.menu_items'); var flag = false; $(this).bind('click', function(){ if(flag) return; setTimeout(function(){ flag = true; menu.slideDown(120); }, 10); }); $(document).bind('click', function(){ menu.slideUp(120); flag = false; }); }); }); 両者ではボタンを2度クリックした時の動作が異なります。 >ちゃんとクリックが終わったあとに hideFunc をバインドしたいのですが、それはなにかいい書き方あれば教えてください 「後者」でやっているように、イベント伝播後にバインドするようにすればご質問の回答になるのかも知れません。 しかし、毎回アンバインドとバインドを繰り返すのも、必ずしもスマートとは言えないのではないでしょうか。(jQueryにはoneという命令もあるみたいですが…)