電子書籍の厳選無料作品が豊富!

.toggle(
function(){ }
, function(){ }
);

こういう形で無名関数の中には.animateを入れてアニメーションを交互するようにしています。
(もうすぐこの形が使えなくなるそうですが…)

やりたいことはもう少し複雑で、まず.toggleするボタンを2つ以上にしたいと思っています。
それぞれのボタンは元々、

ボタン1:設定した"hoge1"を押すとあるテキストエリアが存在するボックスが大きくなったり小さくなったりする。hoge1ボタンもそれに合わせてwidthが大きくなったり小さくなったりする。

ボタン2:"hoge2"を押すとテキストエリアに対して.val("特定のテキスト").focus();するようにして"特定のテキスト"を追加してその後フォーカスするようなボタン。

これらは別々にちゃんと動いていまして、そこまでは出来てるんですが
ボタン2の"hoge2"に、押したら 『ボックスが開いた上でテキスト追加のフォーカス』 という動作を追加したいと思い

$(".hoge1, .hoge2").toggle(function(){
$(".textareabox").animate({width:"300px", height:"toggle", opacity:"toggle"});
$(".hoge1").animate({width:"300px"});
},function(){
$(".hoge1").animate({width:"150px"});
$(".textareabox").animate({width:"150px", height:"toggle", opacity:"toggle"});
});

こういう風にボタンを2つともセレクトすると、どちらか一方のみを使うのであれば動くんですが
当たり前のことに"hoge1"を一度だけ押してから"hoge2"を押すと
.hoge1のwidthは戻らずに、.textareaboxのみ引っ込んで(toggleして)、そこからずれていきます。

ややこしいのですが、場合分けすると

(".hoge1")をクリックしたら
未アニメート時:出す
既アニメート時:ひっこめる

("hoge2")をクリックしたら
未アニメート時:出して.val().focus()
既アニメート時:出したままで.val().focus()

こういうことにしたいです。.val.focusは別でscript書いてます。
:not(:animated)とかいうのをググって見つけたんですがいまいちわかりません。

初心者なので前提からしてどこか間違ってるかもしれませんが
どなたかお知恵拝借願います。。。

A 回答 (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")の戻り値が単位付きだったかどうか記憶していませんが、こんな考え方でもご希望の処理ができると思います。

あと、更に言うならば、回答の例やご提示の処理も含めて、アニメーション中に次のイベントが発生した場合の対処を記述しておいたほうが、より良い記述となることでしょう。
    • good
    • 0
この回答へのお礼

ありがとうございます!
回答2と1を何度も見直し私も同じ結論に達しまして、hoge1の状態をflagに入れてうまく動作させることが出来ました!
hoge2のときは出したままにさせる、というのはtoggleだとflagだけでは何度か押すとtoggleしてしまうため、show()を使うことで回避しました。
ご教授ありがとうございました。

お礼日時:2013/04/27 17:37

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つ作れば良いということですかね?
変数を作るとのこと、参考になります。ちょっと試してみます。

補足日時:2013/04/27 03:19
    • good
    • 0

.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を押したとき、もしボックスが開いていたら開いたままにする、ができないような気がするのですがどうでしょうか?

補足日時:2013/04/26 22:41
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!