<%@ Page Language="C#" AutoEventWireup="true" %>
<html>
<head><title></title></head>
<body>
    <form id="form1" runat="server">
    <script type="text/javascript">
    var d = document.createElement("div");
    document.body.appendChild(d);
    </script>
    </form>
</body>
</html>

寫了如上的Code,又被Operation Aborted的Error搞得七葷八素...

之前雖然有寫過類似的TIP,不過顯然當時的結論不夠精確。我並沒有將Code放在Table中間,但一樣會發生問題。這回我倒是Google到了MS的官方文件,搞清楚了問題的根源: (依照KB的說法,它是個Bug,卻歷經IE5.5->IE6->IE7,代代相傳,不簡單呀!)

This problem occurs because a child container HTML element contains script code that tries to modify the parent container element of the child container.

原來在<div></div>裡執行document.body.appendChild就算是變更Parent的內容,並不是我之前所認知的<table></table>。雖然在我的程式中沒有出現<div></div>,但是ASP.NET在產生form1的HTML Code時會自動用一個div將所有的表單內容物都包起來,就符合了在<div></div>中appendChild的情境而導致錯誤。

知道了原因,要解決很簡單,將<script></script>移到</form>之後即可,收工!
發現一件悲慘的事,我真正要應用的場合有套用MasterPage,<form>被放在MasterPage那一層,因此在網頁裡不可能將Code放到</form>之後... orz

想了一下,找到了個法子,既然在<div>中動手不成,所以我就改成:
window.setTimeout('document.body.appendChild(d);',1);

薑!薑!薑!薑... 搞定收工! 這次是真的。


Comments

# by Ammon

建議對 DOM 的操作一律放在 window.onload 中或之後執行 若擔心window.onload 被重複蓋過 使用jQuery的 $(document).ready([function]) 或 $([function]) 或是將function push到Array中在 window.onload時再一個一個呼叫都是不錯的方式

# by Jeffrey

To Ammon, 同意! 您所提掛onload Event的做法,ASP.NET AJAX Client Script裡也有幾個小武器可用: 1.$addHandler可以同時支援掛載多組Event而不必擔心彼此覆寫。 2.Array.enqueue()與Array.dequeue()的現成Queue機制可借來處理逐序執行。 這陣子用Javascript打巷戰,發現Microsoft AJAX Client Library有不少寶藏,過陣子再整理整理分享。

Post a comment