scriptaculousのEffectで仕込んでしまったバグ

ソースを全て載せるわけにはいかないが、
scriptaculousを使っていたら、下記のソースのようなことが起きた。

/**
 * エフェクト付きでfoo領域を消して、bar領域を表示する
 */
function foo_blindup(){
  Effect.BlindUp('foo', { // fooが最終的には表示されなくなる
    afterFinish: function(){
      Eeffect.BlindDown('bar');
    }
  });
  $('foo_ul').update(''); // foo領域内のfoo_ul領域内をクリアする
}

/**
 * foo領域が表示されていれば、処理を行う
 */
function foo_exec(){
  if($('foo').visible()){
    // fooが表示されているときの処理
    $('foo_ul').update('<li>test</li>');
  }
  // 他にやりたい処理
}

// fooを消して、barを表示する
foo_blindup();
// fooが表示されていないので、if文内の処理はされないはず!
foo_exec();
// ところが、alertで<li>test</li>が出る。
alert($('foo_ul').innerHTML);

原因を探るべく、以下のように修正

// fooを消して、barを表示する
foo_blindup();
// この時点で、alertの中身は空
alert($('foo_ul').innerHTML);
// あとは変わらずに処理
foo_exec();
// ここでも、alertの中身は空に!!
alert($('foo_ul').innerHTML);

foo_exec()の前にalertを出すと処理をパスし、alertを出さないと処理される…。
なんだこれは???と小一時間悩んだ末に気付いたのが、
BlindUp処理が完了し終わってない間にfoo_exec()がコールされているのでは?ということだった。つまり、alertを出した場合は、alertを出している間にBlindUp処理が終わり、foo_exec()がコールされてもif文内の処理が行われないということだ。なんということだ。

結局、以下のように修正。

/**
 * foo領域が表示されていれば、処理を行う
 */
function foo_exec(){
  if($('foo').visible()){
    // fooが表示されているときの処理
    $('foo_ul').update('<li>test</li>');
  }
  // 他にやりたい処理
}

// fooを消して、barを表示する
Effect.BlindUp('foo', { // fooが最終的には表示されなくなる
    afterFinish: function(){
      $('foo_ul').update(''); // foo領域内のfoo_ul領域内をクリアする
      Eeffect.BlindDown('bar');
      foo_exec();  // afterFinish後なので、foo領域はdisplay:none;になっている
    }
}

タグ JavaScript | パーマリンク.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です