IE6 早已退出歷史舞台,但這些導致瀏覽器崩潰的程式碼模式,揭示了排版引擎在處理CSS 表達式、動態 DOM 操作、通用選擇器、註解解析、事件處理器 時的邊界缺陷。理解這些案例,有助於現代前端工程師在撰寫 Polyfill、測試舊系統相容性、或設計測試用例時避開同類邏輯陷阱。
scrollbar-base-color + 絕對定位 Table + JS 動態改變位置<style>
html, body { scrollbar-base-color: #330066; }
.crash { position: absolute; left: 200px; top: 200px; width: 200px; }
</style>
<script>
function galgenfrist() { setTimeout('crashIE();', 1000); }
function crashIE() {
var moveNode = document.getElementById('move');
if (moveNode) { moveNode.style.top = '100px'; moveNode.style.left = '200px'; }
}
</script>
<body onload="galgenfrist();">
<div id="move" class="crash"><table><tbody><tr><td><textarea></textarea></td></tr></tbody></table></div>
觸發條件:IE 專屬捲軸樣式屬性 + 絕對定位容器包含 <table> + <textarea> + JS 延遲修改 style.top/left。渲染引擎在重新計算版面配置時發生未處理的例外。
for...in document.write 迴圈<script>for (x in document.write) { document.write(x); }</script>
現象:Firefox/Chrome 輸出 prototype,IE6 直接進程崩潰。成因:document.write 為原生函式,其 prototype 屬性在 IE 內部實現上導致枚舉器死循環或記憶體存取違規。
* { position: relative } + <table> 直接包裹文字節點<style>* { position: relative }</style>
<table>aaabbbccc</table>
成因:<table> 直屬文字節點違反 HTML 規範(應在 <td> 內),通用選擇器強制所有元素(含匿名生成的表格內部盒模型)套用 position: relative,導致版面配置樹建構邏輯崩潰。
@ 字元緊接註解開頭 /*<style>@;/*</style>
成因:@ 為 at-rule 起始符號,解析器預期後接識別字(如 media, import),卻遇到註解開頭 /*,狀態機無轉移路徑導致解析器崩潰。
<body onload="window()"><body onload="window()"></body>
成因:window 為全域物件,非函式。IE6 嘗試呼叫 window() 時,內部型別檢查失敗觸發未捕獲例外,導致進程終止。現代瀏覽器會拋出 TypeError: window is not a function 並繼續執行。
| 舊時代陷阱 | 現代對應最佳實務 |
|---|---|
| 依賴專屬 CSS 屬性 | 使用標準屬性 + @supports 特性偵測 |
| JS 動態改變版面觸發重排崩潰 | 使用 transform/opacity 動畫、避免強制同步版面配置 |
| 枚舉原生物件屬性導致死循環 | 使用 Object.keys()/getOwnPropertyNames() 明確枚舉 |
| 非標準 HTML 結構 + 激進 CSS | 遵循 HTML 規範、使用語意化標籤 |
| 事件處理器直接呼叫非函式 | 使用 addEventListener、嚴格型別檢查 |
IE6 的崩潰案例雖屬考古學範疇,但其暴露的核心問題——渲染引擎對邊界輸入缺乏防禦性程式設計——在任何時代都值得警惕。今天的 Chrome/Edge/Firefox/Safari 雖已極度穩健,但在開發瀏覽器擴充功能、Electron 應用、或維護舊系統相容層時,這些「負面教材」依然能幫助我們寫出更健壯的程式碼。