問題は、Datepickerのhide()メソッドが、jQueryがそれ自体のhide()メソッドのパラメーターをどのように処理するかを想定していることです。つまり、jQuery 1.4.4に戻って、次のような呼び出しを行った場合
$('#some-element').hide('',someCallback)
jQueryは最初の要素をspeed
パラメーターと見なし、そのパラメーターが式を満たさない限り
speed || speed === 0
jQueryはパラメータを無視し、昔ながらのように関数を実行します
$('#some-element').hide()
つまり、コールバックが呼び出されることはありません。
さて、Datepickerのコードを実装した人は誰でもこの動作を認識し、コールバックを適切にトリガーするようにパラメーターを変更するのではなく、コールバックを手動で呼び出すだけの回避策を考え出しました。
これが4.0.6(OPバージョン)からの抜粋です
else {
// Note: This branch will always execute when one datepicker opening
// triggers the closing of another. Moreover, showAnim === ''
var hideAnim = (showAnim == 'slideDown' ? 'slideUp' :
(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'));
inst.div[hideAnim]((showAnim ? showSpeed : ''), postProcess);
}
if (!showAnim) {
postProcess();
}
一方の日付ピッカーを開くともう一方の日付ピッカーが閉じると、上記のコードは次のようになります。
inst.div.hide('', postProcess); // this is the jQuery.fn.hide function
postProcess();
これは正常に機能します...jQuery1.4.4で。
ただし、それ以降、jQueryは改善され、hideメソッドにコールバックを渡すと、jQueryは終了時に確実に呼び出されるようになりました。したがって、発生している問題は、コールバックpostProcess
が2回呼び出されることです。
解像度
これを修正して、以降のjQueryバージョンで例外がスローされないようにするには、行を削除/コメントアウトするだけで済みます。
if (!showAnim) {
postProcess();
}
さらに、修正を古いバージョンのjQueryと下位互換性を持たせたい場合は、変更する必要があります
inst.div[hideAnim]((showAnim ? showSpeed : ''), postProcess);
に
inst.div[hideAnim]((showAnim ? showSpeed : 0), postProcess);
プランク(4.1.0を使用)
注:4.1.0では、postProcess
メソッドにテストを入れてnull
最初に値をチェックする回避策が導入されました。ただし、これは、コールバックが2回呼び出されるという主要な問題を無視します。