最近有一段程式寫好了,但在 IE tester 測試 IE6 時,不停跳出 "Unspecified error"(無法指出的錯誤)的錯誤訊息。由於 IE tester 提供的錯誤訊息很陽春,指出的行號和檔名搭不上,花了好些時間才找出錯誤。

(錯誤是發生在 xxx.js,但是在錯誤訊息視窗顯示為 ooo.php)

這個問題是這樣發生的:
1. 我有兩個下拉選單 (<select>),它們的下拉值會透過 AJAX 取得。
2. 第一個下拉選單的值改變時,會連動第二個下拉選單。如果 AJAX 傳回來的資料中,第二個下拉選單的值是空的,表示這個下拉選單沒有任何候選值,此時我會把第二個下拉選單隱藏起來。
3. 再次改變第一個下拉選單的值,如果這次第二個下拉選單有候選值,那我就會把第二個下拉選單顯示出來,並且選取第二個下拉選單的第一組值,作為預設值。

這次出問題的地方就在第三個步驟中,設定預設值的地方。原本以為是隱藏了元素的問題,但把元素 show 出來也還是沒用。

Google 了一下,找到這篇文章:《IE6<select>问题: "无法设置selected属性。未指明的错误。”》,作者說他如果在錯誤之處前一行加上 alert,就能正常執行,底下其他人建議他將設值的部分加上 setTimeout。

再看了 《利用 jQuery 將 DOM 元素聚焦 focus() 的六個版本》,裡面也說到這種隱藏元素後要加以處理的問題:

這問題會出現在 IE8 之前的 IE 瀏覽器上,通常發生在 DOM 元素先被隱藏,然後才被顯示出來 (這是常用的 hack 技法),雖然 DOM 元素已經在畫面上看的到,但 DOM 物件狀態還沒改變,導致執行 focus() 函式發生錯誤,這時就要用以上程式來解決。

假設原本的程式如下,

var sOption = '<option value="1">我是選項一</option>';
$(sOption).appendTo("#select1");
$('<option value="-1">全部</option>').insertBefore($("#select1").children().first());
$("#select1").children()[0].selected = true;

改寫時加上 setTimeout 即可。

var sOption = '<option value="1">我是選項一</option>';
$(sOption).appendTo("#select1");
$('<option value="-1">全部</option>').insertBefore($("#select1").children().first());
setTimeout(function(){ $("#select1").children()[0].selected = true; }, 1);









arrow
arrow

    小攻城師 發表在 痞客邦 留言(0) 人氣()