jQueryのIE6のバグを報告したら有名なIE6のバグと言われた件
個人的にはIE6なんてもう対応する気もないんだけど、そういう分けにもいかずハマったので、検証コードを書いてみた。それでも再現するので、これはjQueryのバグかと思い報告してみたら(closed bug: cantfix)を頂きました。
This is a well-known issue with IE6 being unable to update options, and can be fixed with setTimeout or one of the solutions suggested in the links below:
#11564 ($('option').attr('selected', true) does not work on IE6) – jQuery - Bug Tracker
well-known issueという事で、割と知られてるIE6のバグ?みたい。検証コードでも再現したからといって、すぐにバグ報告しないでフォーラムにまず書くべきだったかもなぁ。
ちなみに、ブログに書くのがおっくうで、報告したのはもう3ヶ月も前みたいです。
内容
jQuery+IE6の組み合わせで、JavaScriptエラーが発生します。
<form id="foo"> <select name="foo"> </select> <button>run</button> </form>http://jsfiddle.net/dmethvin/SVTUm/
option要素はjQueryで組み立てるつもりで、option要素を持たないselect要素をhtmlに書いてます。
$(function(){ $('button').click(function(e){ e.preventDefault(); var $select = $(this.form).find("select").empty(); var array = ['ein', 'zwei', 'drei']; for( var i=0; i<array.length; i++ ){ var $option = $('<option>'); $option.val('').text(array[i]); $select.prepend($option); } $select.children(':first').prop('selected', true); }); });​http://jsfiddle.net/dmethvin/SVTUm/
そしてjQueryでoption要素をいくつか追加し、どれかをselectedにしようとすると・・・IE6限定でJavaScriptエラーが発生します。>=IE7*1やその他のモダンブラウザでは発生してません。
解決方法
$(function(){ $('button').click(function(e){ e.preventDefault(); var $select = $(this.form).find("select").empty(); var array = ['ein', 'zwei', 'drei']; for( var i=0; i<array.length; i++ ){ var $option = $('<option>'); $option.val('').text(array[i]); $select.prepend($option); } setTimeout( function() { $select.children(':first').prop('selected', true); }, 1); }); });​http://jsfiddle.net/dmethvin/SVTUm/1/
setTimeout()で非同期処理にすると回避できるようです。
Because it is a timing issue it can't be fixed within jQuery core without introducing even more issues (e.g., what if other things run before we select the option in the timeout?)
#11564 ($('option').attr('selected', true) does not work on IE6) – jQuery - Bug Tracker
英文読解力が足りずに、意図を完全に汲み取れてないんですが、これはタイミングの問題らしい。提示されたstack over flowも読んでみると、JavaScriptで生成した要素にJavaScriptがアクセスする場合の、生成とアクセスのタイミングの事を言ってるような気がしました。
補足
<form id="bar"> <select name="bar"> <option value="">dummy</option> </select> <button>run</button> </form>​http://jsfiddle.net/dmethvin/SVTUm/
option要素を最初から入れておけば、たとえそれを$().empty()
で消して、改めてoption要素を積んだとしても、エラーは発生しませんでした。
jsdo.it
さっきからJSFiddleからばかり貼ってるけど、最初はjsdo.itで検証コード書いてたんだよね。
The site jsdo.it does not work for me in IE6. This JSFiddle reproduces the issue:
#11564 ($('option').attr('selected', true) does not work on IE6) – jQuery - Bug Tracker
jsdo.itって、UI英語にしてるし海外でもそこそこ使われてるのかなーとか思ったんだけど、「動かないからJSFiddleで作りなおした」って言われてしまいました。
http://jsfiddle.net/dmethvin/SVTUm/
http://jsfiddle.net/dmethvin/SVTUm/1/
確かにこのJSFiddleは、Saveする度にURLが発行されて、ちょっとしたバージョン管理みたいな感じになってて便利そう。今回の、動かないコードと、直したコードもスッキリとしてるし。ただ、まちがってSaveしちゃっても、URLのカウントアップは取り消せないみたい。