1. 程式人生 > >為 SELECT.options 物件增加或刪除選項的方法在各瀏覽器中的支援情況不同

為 SELECT.options 物件增加或刪除選項的方法在各瀏覽器中的支援情況不同

DOM 2 HTML 中分別定義了 HTMLSelectElement、HTMLOptionsCollection 和 HTMLOptionElement 介面,它們分別定義了若干屬性和方法來獲知或操作 SELECT 及 OPTION 元素。

HTMLSelectElement 介面定義了以下屬性及方法:

  • length: 獲取 SELECT 元素中 OPTION 的數量;
  • options: 獲取 SELECT 包含的 OPTION 元素集合,其返回值型別為 HTMLOptionsCollection;
  • add(element, before): 向 SELECT 中新增一個 OPTION,引數 element 指定要新增的 OPTION 物件,before 指定了插入到哪個 OPTION 之前,如果值為 'null',則插入 SELECT 尾部;
  • remove(index): 從 SELECT 中刪除一個 OPTION,引數 index 指定了要刪除的 OPTION 索引。

HTMLOptionsCollection 介面是一個 OPTION 節點列表,可以通過索引或某個 OPTION 節點的 name 或 id 屬性訪問該 OPTION。 它定義了 'length' 屬性,用來獲取當前 OPTION 節點列表的長度,作用同 HTMLSelectElement 的 'length' 屬性。

問題描述

各瀏覽器對標準的支援有差異,並且他們實現了非標準的新增和刪除 OPTION 元素的方法,在使用這些方法時,可能造成相容性問題。

造成的影響

如果使用了存在相容性問題的新增或刪除 OPTION 元素的方法,將可能導致指令碼異常,功能不可用。

受影響的瀏覽器

所有瀏覽器

問題分析

除了標準提到的方法外,各瀏覽還實現了另外幾種新增、刪除 OPTION 元素的方法,各瀏覽器對這些方法的支援程度不一致。

非標準的新增 OPTION 的方法:

  • select.add(option):SELECT 物件的方法,直接插入引數 option 到尾部;
  • select.add(option, index):在指定的 OPTION 列表索引 index 之前插入引數 option;
  • options.add(option, before):OPTION 節點列表(實現 HTMLOptionsCollection)的方法,效果同 HTMLSelectElement.add;
  • options.add(option):同第一個方法;
  • options.add(option, index):同第二個方法;
  • options[index] = option:直接在 OPTION 節點列表上新增元素。

非標準的刪除 OPTION 的方法:

  • select.remove(option):SELECT 物件的方法,刪除引數指定的 OPTION 物件;
  • options.remove(index):OPTION 節點列表的方法,同 HTMLSelectElement.remove;
  • options.remove(option):同第一個方法;
  • options[index] = null:直接在 OPTION 節點列表上設定元素為 null。
  • 分析以下程式碼:

    1. <styletype="text/css">select {height:100px;}</style>
    2. <table>
    3.   <tbody>
    4.     <tr>
    5.       <td>
    6.         <selectid="s1"multiple="multiple">
    7.           <optionvalue="1">111</option>
    8.           <optionvalue="2">222</option>
    9.         </select>
    10.       </td>
    11.       <td>
    12.         <selectid="s2"multiple="multiple">
    13.           <optionvalue="1">111</option>
    14.         </select>
    15.       </td>
    16.       <td>
    17.         <selectid="s3"multiple="multiple">
    18.           <optionvalue="1">111</option>
    19.           <optionvalue="2">222</option>
    20.         </select>
    21.       </td>
    22.       <td>
    23.         <selectid="s4"multiple="multiple">
    24.           <optionvalue="1">111</option>
    25.         </select>
    26.       </td>
    27.       <td>
    28.         <selectid="s5"multiple="multiple">
    29.           <optionvalue="1">111</option>
    30.         </select>
    31.       </td>
    32.     </tr>
    33.     <tr>
    34.       <td><buttontype="button"onclick="remove(1);">select.remove(index)</button></td>
    35.       <td><buttontype="button"onclick="remove(2);">select.remove(option)</button></td>
    36.       <td><buttontype="button"onclick="remove(3);">options.remove(index)</button></td>
    37.       <td><buttontype="button"onclick="remove(4);">options.remove(option)</button></td>
    38.       <td><buttontype="button"onclick="remove(5);">options[index] = null</button></td>
    39.     </tr>
    40.   </tbody>
    41. </table>
    42. <divstyle="border:2px solid;padding:3px;width:800px;"id="info"></div>
    [javascript] view plaincopy
    1. <script type="text/javascript">  
    2.   function $(id){return document.getElementById(id);}  
    3.   function newOpt(text, val){returnnew Option(text, val);} 1  
    4.   function info(method, msg){$("info").innerHTML += "<strong>" + method + "</strong> : " + msg + "<br />";}  
    5.   //建立n個 OPTION 物件
    6.   var opt1 = newOpt("select.add(option, null)", 2),  
    7.     opt2 = newOpt("select.add(option)", 2),  
    8.     opt3 = newOpt("options.add(option, null)", 2),  
    9.     opt4 = newOpt("options.add(option)", 2),  
    10.     opt5 = newOpt("options[index] = option", 2),  
    11.     opt6 = newOpt("select.add(option, option)", 2),  
    12.     opt7 = newOpt("select.add(option, index)", 2),  
    13.     opt8 = newOpt("options.add(option, option)", 2),  
    14.     opt9 = newOpt("options.add(option, index)", 2),  
    15.     s1 = $("s1"),  
    16.     s2 = $("s2"),  
    17.     s3 = $("s3"),  
    18.     s4 = $("s4"),  
    19.     s5 = $("s5");  
    20.   //使用n種方法新增 OPTION 到 SELECT 中
    21.   try { s1.add(opt1, null); } catch(e) { info("select.add(option, null)", e) }  
    22.   try { s2.add(opt2); } catch(e) { info("select.add(option)", e) }  
    23.   try { s3.options.add(opt3, null); } catch(e) { info("options.add(option, null)", e) }  
    24.   try { s4.options.add(opt4); } catch(e) { info("options.add(option)", e) }  
    25.   try { s5.options[1] = opt5; } catch(e) { info("options[index] = option", e) }  
    26.   try { s1.add(opt6, s1.lastChild); } catch(e) { info("select.add(option, option)", e) }  
    27.   try { s1.add(opt7, 1); } catch(e) { info("select.add(option, index)", e) }  
    28.   try { s3.options.add(opt8, s3.lastChild); } catch(e) { info("options.add(option, option)", e) }  
    29.   try { s3.options.add(opt9, 1); } catch(e) { info("options.add(option, index)", e) }  
    30.   function remove(type){  
    31.     var method = "";  
    32.     try {  
    33.       switch(type) {  
    34.         case 1 :  
    35.           method = "s1.remove(0)";  
    36.           break;  
    37.         case 2 :  
    38.           method = "s2.remove(s2.firstChild)";  
    39.           break;  
    40.         case 3 :  
    41.           method = "s3.options.remove(0)";  
    42.           break;  
    43.         case 4 :  
    44.           method = "s4.options.remove(s4.firstChild)";  
    45.           break;  
    46.         case 5 :  
    47.           method = "s5.options[1] = null";  
    48.           break;  
    49.       }  
    50.       eval(method);  
    51.     } catch (e) {  
    52.       info(method, e);  
    53.     }  
    54.   }  
    55. </script>  

    上述程式碼首先使用了標準及非標準方法向各 SELECT 元素中添加了 OPTION,然後點選各按鈕使用各種刪除方法刪除 OPTION, 根據丟擲的異常資訊,我們可以辨別出哪些方法在瀏覽器中不支援,彙總測試結果如下表:2

    type method IE6 IE7 IE8(Q) IE8(S) Opera Firefox Chrome Safari
    add OPTION select.add(option, null) N Y Y Y
    select.add(option, option) N Y Y Y
    select.add(option, index) Y Y N N3
    select.add(option) Y Y N Y
    options.add(option, null) N Y N4 N4
    options.add(option, option) N Y N N
    options.add(option, index) Y Y Y Y
    options.add(option) Y Y Y Y
    options[index] = option Y Y Y Y
    remove OPTION select.remove(index) Y Y Y Y
    select.remove(option) Y Y Y Y
    options.remove(index) Y Y N Y
    options.remove(option) Y Y N Y
    options[index] = null Y Y Y Y

    注1:這裡使用 new Option(text, value) 的方式建立新的 OPTION 物件,也可以使用 new Option([text[, value[, defaultSelected[, selected]]]]) 或 document.createElement("option") 建立。建立 OPTION 物件的方法於本文測試結果無影響。

    注2:Y 表示支援該方法,N 表示不支援。

    注3:並沒有實現在指定索引前插入 OPTION 的功能,只是實現了向 SELECT 元素尾部插入元素。

    注4:並不是向 SELECT 元素的尾部插入 OPTION,而是插入到 SELECT 的首部。

    解決方案

    1. 在新增 OPTION 元素時

    • 如果需要向指定索引前插入 OPTION,可以使用 options.add(option, index);
    • 如果需要向 SELECT 尾部新增 OPTION,可以使用 options.add(option);
    • 如果需要向指定索引處新增(或更改) OPTION,可以使用 options[index] = option。

    2. 在刪除 OPTION 元素時

    • 如果想刪除指定索引處的 OPTION 元素,可以使用 select.remove(index) 或 options[index] = null;
    • 如果想刪除某個指定的 OPTION 元素,可以使用 select.remove(option);
    • 如果想刪除 SELECT 中所有 OPTION,可以使用 select.length = 0 或 options.length = 0。