- ベストアンサー
jQueryで複数の.toggleボタンを使いたい場合の問題とその解決方法
- jQueryの.toggleを使用してアニメーションを交互に切り替えるためには、ボタン1とボタン2の動作を個別に設定する必要があります。
- .hoge1ボタンをクリックした場合、アニメーションが実行されたかどうかを確認し、実行されていない場合はテキストエリアを表示します。
- .hoge2ボタンをクリックした場合、アニメーションが実行されたかどうかを確認し、実行されていない場合はテキストエリアを表示し、特定のテキストを追加してフォーカスします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
A No1、2です。 ".textareabox"の動作のheight:"toggle", opacity:"toggle"は、要素の状態に応じてtoggleされますので、イベントの処理をtoggleで行う必要はないでしょう。 一方で、hoge1は自分自身が動作対象でありながら他にもトリガーが存在するために単純にtoggleでは処理しにくいことになっています。 結局のところ、textareaboxもhoge1もwidthはhoge1の状態に応じて処理内容を決め、height、opacityはtextareaboxに対してのtoggleで処理すればよいことになりませんか。 >つまりこの場合flagを2つ作れば良いということですかね? 2つでもよいですが、hoge1の状態が判定できさえすれば良いように思えます。 例示のようにflagなどの状態変数を作成する方法が汎用的と思いますが、変数を使わずに直接要素を調べて判断する方法もあるでしょう。 $(".hoge1, .hoge2").click(function(){ var f = $(".hoge1").css("width") == "150px"; $(".hoge1").animate({width:f?300:150}); $(".textareabox").animate({width:f?250:150, height:"toggle", opacity:"toggle"}); }); 書きっぱなしなので、動作確認していません。 .css("width")の戻り値が単位付きだったかどうか記憶していませんが、こんな考え方でもご希望の処理ができると思います。 あと、更に言うならば、回答の例やご提示の処理も含めて、アニメーション中に次のイベントが発生した場合の対処を記述しておいたほうが、より良い記述となることでしょう。
その他の回答 (2)
- fujillin
- ベストアンサー率61% (1594/2576)
A No1です。 >ボタン2を押したとき、もしボックスが開いていたら >開いたままにする、ができないような気がするのですが >どうでしょうか? 「開く」とか「出す」というのがどのような動作を意味しているのかよくわからないのですが、要は、状態に応じて処理内容を変えたいのだと想像しました。 A No1にも書きましたが、toggleだと要素ごとにオン/オフの状態を記憶してしまうために、実際に見えている状態に連動した値にならないだけでなく、ひとつの状態に対して複数の変数を作っていることになります。 これを回避するために、実際の状態と整合した状態の記憶用の変数を自前で設定してあげれば、その値(=状態)によって処理内容を決定することができます。 A No1の変数 flagがこれに該当します。 複数の同様の処理が可能なようにクロージャー的な記述になっていますが、わかりやすくするなら、グローバルな状態変数を作成しておくと考えればよろしいでしょう。
補足
すいません、説明不足でした。 $(".hoge1, .hoge2").toggle(function(){ $(".textareabox").animate({width:"250px", height:"toggle", opacity:"toggle"}); $(".hoge1").animate({width:"300px"}); },function(){ $(".hoge1").animate({width:"150px"}); $(".textareabox").animate({width:"150px", height:"toggle", opacity:"toggle"}); }); ちょっと1度目に書いたコードと2行目のwidthが違うのですが、1度目が間違いでこうでした。 このコードでやっているのは、animate()のheightとopacityをtoggleという値によって出てきたり消えたりを繰り返しています。".textareabox"にはCSSシートでdisplay:none;を初期設定としています。 そして、height:"toggle", opacity:"toggle"とやると縦に大きくなりながら透明なボックスが無透明になる様子がアニメートされます。 つまり、テキストエリアボックスは消えたり出てきたりします。widthはまぁhoge1に合わせて大きくしてるだけです。 それと同時に、ボタン自身は横幅が大きくなったり小さくなったりします。 つまり、一回hoge1を押すと1.ボタンの横幅が大きくなる、2.テキストエリアボックスが現れる、という2つのアニメーションを同時にやっていることとなります。 なので、単純にそう動作するボタンを2つ作るんであればclassを同じにするだけでいけそうなんですが つまりこの場合flagを2つ作れば良いということですかね? 変数を作るとのこと、参考になります。ちょっと試してみます。
- fujillin
- ベストアンサー率61% (1594/2576)
.hoge1、.hoge2のどれをクリックしても、交互に状態を変えたいという意味でしょうか? 「toggle」は各要素ごとに状態を記憶するようになっているようですので、ご提示の記述方法ですとご質問のような動作になると思います。 グループの要素のどれをクリックしても、まとめて同じスイッチのオン/オフをするようにしたいのであれば自前で定義してあげるとか… var groupToggle = function(e, w1, w2){ var flag = false; return function(){ if(flag = !flag) e.animate({width:w1}); else e.animate({width:w2}); } } var gt1 = groupToggle($(".hoge1"), 300, 150); $(".hoge1, .hoge2").click(function(){ gt1(); }); みたいな感じ。 あるいは、ご提示の記述に近い形にするなら、代表して状態を記憶するためのダミーの要素を作成しておいて、その状態にあわせて処理を実行するようにしてあげるとか。 $("#fuga").toggle(function(){ $(".hoge1").animate({width:"300px"}); },function(){ $(".hoge1").animate({width:"150px"}); }); $(".hoge1, .hoge2").click(function(){ $("#fuga").click(); }); みたいなのでもいけると思います。
補足
ありがとうございます。 それだと、ボタン2を押したとき、もしボックスが開いていたら開いたままにする、ができないような気がするのですがどうでしょうか?
お礼
ありがとうございます! 回答2と1を何度も見直し私も同じ結論に達しまして、hoge1の状態をflagに入れてうまく動作させることが出来ました! hoge2のときは出したままにさせる、というのはtoggleだとflagだけでは何度か押すとtoggleしてしまうため、show()を使うことで回避しました。 ご教授ありがとうございました。