前幾天我在寫用 JavaScript 自動轉換 Tag 註記的工具時,發現 Opera 瀏覽器在操作 Unknown HTML 元素 (即自定元素) 的 DOM 方法中有 bug ,不能正確取代或插入其他節點在 Unknown HTML 元素之節點後。如果用取代方法 (replaceChild) 甚至會切斷 DOM 結構。
我設置了一個最簡單的測試環境,使用三種瀏覽器: MSIE 6, Firefox 1.5, Opera 9.1 (build 8679) 測試操作取代及插入動作。 MSIE 和 Firefox 都如預期般正確操作,唯 Opera 有錯誤。
案例一、使用一般 HTML 元素
首先,我想先確認使用一般 HTML 元素時, Opera 會不會有問題。因此,我在 HTML 文件中放了四個節點元素, 3 個 paragraph element (<p>) , 1 個 break element (<br>) 。
我以 break element 為目標,分別嘗試三個節點操作動作:一、節點取代動作;二、在節點之後插新節點;三、將新節點插入在節點之前。
節點取代動作
建立一個 image element (<img>) ,以其取代 break element 節點。
將下面的 JavaScript 程式碼複製到 HTML 文件中,請放在 <body> 區塊內。
在節點之後插新節點
建立一個 image element (<img>) ,將其插入在 break element 節點之下。
將下面的 JavaScript 程式碼複製到 HTML 文件中,請放在 <body> 區塊內。
將新節點插入在節點之前
建立一個 image element (<img>) ,將其插入在 break element 節點之前。
將下面的 JavaScript 程式碼複製到 HTML 文件中,請放在 <body> 區塊內。
三種瀏覽器皆正確完成以上操作動作。
案例二、使用自定元素
確定一般 HTML 元素不會有問題後,接著要測試自定元素的情形,這是本文的主題。承前面的例子,只是我把 break element (<br>) 換成了自定元素 (<tags>) ,其他動作皆相同。
即使面對一個自定元素 (Unknown element) , MSIE 和 Firefox 仍然正確地完成操作動作, Opera 卻出現錯誤。
Opera 在完成取代動作後,卻砍斷了 DOM 結構,原來自定元素之節點後的樹枝也被移除了。
插入在節點之後的動作,卻是把新節點插入在最後面位置,而不是自定元素後的節點 (<p>Thrid</p>) 之前。透過觀察 d.nextSibling 和 d.nextSibling.firstChild 兩個體之內容,也發現 Opera 無法正確處理自定元素的屬性。
Opera 唯有插入在節點之前的動作正確。
在 Ajax 技法中,上述節點操作動作的使用機會很高。而從本文的測試結果中顯示,如果你使用了自定元素,而 Opera 的使用者反應他們無法使用你的網站時,多半就是碰到本文的狀況了。