昨天我和同僚在為這個Menu繼續添加新功能時,發現這個Popup菜單導緻IE Crash的問題變得十分頻繁,幾乎每做8,9步顯示菜單的操作就能導緻IE
6 Crash。
// 這樣的問題真是讓人無法忍受啊!!!
能搞出: The
instruction at "0x4a5b19d6" referenced memory at "0x00000020". The memory could
not be "red". 這樣的問題,顯然已經完全操出了腳本的能力。
雖然沒有固定的複現這個問題的步驟,但是下面這個頁面還是很容易的在安裝了該hotfix的IE上引發Crash:

<html>

<head>
<script language="javascript">
var g_popup = null;
function ShowPopup(elmt)
{
g_popup = window.createPopup();
var popBody = g_popup.document.body;
popBody.innerHTML = '<table style="text-align: center; height: 100%; border: dotted 1px blue">'
+ '<tr><td><button onclick="ShowPopup(this)">Show Popup Window</button><br><br>'
+ '藍色虛線框中是一個Popup Window。</td></tr></table>';
g_popup.show(100, 100, 400, 200, elmt );
}
</script>

</head>

<body>

<button onclick="ShowPopup(this)">Show Popup Window</button>

</body>

</html>
// 儲存為*.htm檔案就可以了,打開後反複點選第一個"Show
Popup Window",大概10次左右就會Crash。
進一步分析這個問題,再看看下面這兩個改進的示例:
<script language="javascript">
var g_popup = null;
function ShowPopup(elmt)
if ( !g_popup ) g_popup = window.createPopup();
var popBody = g_popup.document.body;
popBody.innerHTML = '<table style="text-align: center; height: 100%; border: dotted 1px blue">'
+ '<tr><td><button onclick="ShowPopup(this)">Show Popup Window</button><br><br>'
+ '藍色虛線框中是一個Popup Window。</td></tr></table>';
g_popup.show(100, 100, 400, 200, elmt );
}

</script>
g_popup = window.createPopup();
+ '<tr><td>藍色虛線框中是一個Popup Window。</td></tr></table>';

新的版本在反複點選"Show Popup
Window"後不會Crash(至少我點了很久很久沒有Crash...)。
仔細分析,我們可以發現,這個問題應該是IE記憶體洩露造成的。在第一個改進中,我們緩存了g_popup,反複點選其實隻使用了一個popup視窗;而在第二個改進中,我們把從popup視窗内部元素對parent頁面函數的引用去掉了。這樣一來我們可以很容易的發現出錯頁面的原因:反複的生成并丢棄了對parent頁面腳本元素有引用關系的popup視窗,就會使IE
Crash掉。
那麼大概知道了Crash的原因後,可以完全有效的避免這個Crash嗎?我認為答案是否定的,因為使用Popup視窗來構成的菜單,不太可能絕對的不去引用Parent頁面中的腳本方法,同時也很難有絕對安全的辦法來避免産生野popup執行個體(沒有被頁面引用的popup,類似野指針概念)。退一萬步,就算都避免了,那麼這種cut過的popup還有什麼實用意義呢?
除了自己小心,那麼最有隻能祈禱M$趕快推出新的更新檔的更新檔的更新檔。。。
本文轉自部落格園鳥食軒的部落格,原文連結:http://www.cnblogs.com/birdshome/,如需轉載請自行聯系原部落客。