jQueryでoption要素を追加した際の諸問題
jQueryで任意のoption要素を追加するには、append()やprepend()を利用するのが手軽。
$('#target').append($('<option>').attr({ value: 'xxx' }).text('xxxxxxx'));
だが、この操作はIEの場合に問題が生じる。v1.1.3.1以前ではoption要素を追加しても幅が調整されない不具合があり*1、v1.2.3ではoption要素を増やした直後にそのvalue値をval()で設定しようとすると、
「selected プロパティを設定できませんでした。 未定義のエラーです」
というスクリプトエラーが発生する*2。これらの問題はselect要素ごと作り直してしまうことで回避できる。
$('#target').after($('#target').clone()); $('#target').remove();
一時的に同一のidを持つ要素が二つできてしまうが、jQueryはこれも問題なく扱える。after()で追加したselect要素のコピーは正しい幅を持ち、val()による値のセットも問題なく行える。after()の戻り値は$('#target')なので、一行で書くこともできる。
$('#target').after($('#target').clone()).remove();
上記はreplaceWith()と等価なはずなのだが、何故かこちらではval()のエラーが回避されない。
$('$target').replaceWith($('#target').clone());
このメソッドはv1.2.3の460行目付近に定義されている。
replaceWith: function( value ) { return this.after( value ).remove(); },
回避策はもう一つある。option要素を増やした直後に
$('#target').width();
上記のようにwidth()を呼び出すと、v1.1.3.1では幅が調整され、v1.2.3では以後val()による値のセットでエラーが生じなくなる。ソースを追ってみたが、理由はよく判らない。
更に言うと、v1.2.3ではoption要素を増やした後に任意の引数でalert()を呼び出してからval()をセットすると、何故かエラーが発生しない。
$('#target').append($('<option>').attr({ value: 'xxx' }).text('xxxxxxx')); alert('press any key'); // この一行がないとエラーになる $('#target').val('xxx');
意味不明。誰かこのメカニズムを解明できたら、是非教えてください。