做者: xcntime 發表於 2010-08-11 10:49 原文連接 閱讀: 0 評論: 0javascript
去年就想將IE的bug系統地整理下,但一直都忙於工做、學習沒有完成,看到這篇E文後,我絕不猶豫的放下了手中的工做將之翻譯出來。
因爲是第一次譯文,因此錯誤在所不免,歡迎你們批評指正。css
原文:Ultimate IE6 Cheatsheet: How To Fix 25+ Internet Explorer 6 Bugshtml
翻譯:http://www.vfresh.org/w3c/727(譯文對原文進行了補充)前端
對IE6最好的策略就是不去兼容它。java
好吧,我知道你的難處,你不得不去兼容IE6這個狗血的瀏覽器,所以不得不在兼容IE6上花費不少時間。對此,我很有同感,來讓我來幫助你吧。jquery
我不會象許多文章那樣讓你去抵制IE6,這並不會幫助到你(無可奈何時)去兼容IE6;由於IE6依舊佔有必定的市場份額,你沒法放棄IE6。本文將幫助你來解決這個難題。web
我查閱過不少資料來摘錄這些解決方案(有些是我本身提供的),如今我作成手冊提供給你們搞定IE6這個傢伙。我儘量的提供了最優解決方案而不是一些hacks,而且提供了一些相關的資料。若是你發現有更好的方法或者本文有錯誤,請聯繫我。canvas
在討論IE6的BUG及如何修復以前,有必要先講一些策略去避免這些惱人的問題——正所謂防患於未然 。api
兼容IE6的第一步就是單獨對IE進行兼容,你針對IE6所寫的代碼隻影響IE6。瀏覽器
解決IE6佈局方面的BUG很是的惱人!特別是在實現一個精美的設計稿時。
ie6有着一些行爲方面的BUG,究其緣由是IE6版本太老了,不能無缺地支持CSS2更不支持CSS3,並且微軟執拗的使用了其私有方法。
IE6有着數不盡的JavaScript bug,這裏我不會講解每個IE6下JavaScript的bug,只摘取其中幾個廣泛的問題來討論。
在討論IE6的BUG及如何修復以前,有必要講敘一些策略去避免這些惱人的問題——正所謂防患於未然 。
據Market Share統計,目前(2009年8月)IE6 的市場佔有率爲25.25%,可是其餘地方的統計明顯要低,爲18.1%;儘管統計結果不一樣,但都呈現出了降低的趨勢(翻譯此文時,淘寶的IE6用戶已從70%跌破至69%)。可是最重要的,仍是你本身網站的統計數據。若是你對你的網站進行了流量分析,那麼IE6的佔有率是否值得你去針對IE6進行開發?這須要你本身去權衡。
若是你網站絕大部分訪問者不使用IE6而且不付費給你,那麼你沒必要特地區針對IE6作兼容,從而節省時間、精力及資金。
在作設計的同時考慮代碼的實現,能夠避免一些佈局上的問題。再複雜的設計稿也能用簡潔的代碼實現,若是你使用了過於繁冗的標籤,那麼你須要從新修繕設計稿。
若是你有豐富的開發經歷,攻克過不少種佈局難題,記錄下你的解決方案,在之後碰到相同問題時能夠提升開發效率。
使用一個錯誤的文檔聲明會觸發quirks mode(怪異模式),正確的文檔聲明能夠保證你的頁面在全部瀏覽器下保持一致的效果。使用其中的一個文檔申明:HTML 5
, HTML 4.01 Strict
, HTML 4.01 Frameset
, HTML 4.01 Transitional
, XHTML 1.0 Strict
, XHTML 1.0 Frameset
, XHTML 1.0 Transitional
, or XHTML 1.1
<!DOCTYPE HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
我曾據說過有些人認爲校驗代碼沒有任何實用價值,但我不這麼認爲。校驗僅僅只需花費一點點時間,並且將受益於全部瀏覽器而非僅僅IE6;驗證確保了向後兼容而且易於維護。至少也得驗證XHTML!惟一能夠忽略驗證的狀況是在你打算使用CSS3時。
在寫代碼的過程當中,一開始在標準瀏覽器中測試(如 Firefox, Opera, Chrome等),而後再去測試非標準瀏覽器(如IE6/IE7),由於這些標準瀏覽器都遵循w3c標準,大多的處理方式都相同。你能夠分開來單獨去兼容「特別」的IE瀏覽器,這樣作能規範你的代碼,你將會所以擁有紮實的基礎;並且若是你再也不須要兼容這些非標準瀏覽器,你能夠一次性刪除這些修復兼容性代碼。
漸進加強(Progressive Enhancement)是爲了確保沒有頁面特效後基本功能也是可用的。簡單來說,漸進加強是指在確保頁面在禁用JavaScript後能正常運做後,再對頁面添加各類特效(JavaScript動畫、Ajax異步等等)。咱們一樣能夠運用「漸進加強」原則來使用CSS3(或者一些CSS2)、HTML5以及其餘IE6所不支持的web規範。
某些狀況下,是沒法讓全部用戶在任何瀏覽器下都徹底如出一轍,特別是那些使用IE6的用戶。運用漸進加強策略,能夠保證讓那些用戶至少使用到你網站(或網絡應用)的基本功能。
每一個瀏覽器都有各自不一樣的預設樣式,在你的樣式表以前使用預設樣式(CSS Reset)能夠避免在以後編寫冗長的瀏覽器兼容樣式。在網上有不少CSS Reset可供參考。
body,div,ul,ol,li,h1,h2,h3,h4,h5,h6,form,fieldset,input,textarea,p,th,td {margin:0;padding:0;}
若是你的網站使用了較多的JavaScript特效,建議使用JavaScript框架。大部分的js框架都兼容了包括IE6在內的各類瀏覽器。可選的框架有不少,但通常能用一種框架實現的效果必定能夠用另一種框架實現,因此你能夠根據我的喜愛來選擇合適的框架。
如下是一些經常使用的JavaScript框架:
強烈推薦實用MooTools,但若是你是入門者,仍是建議使用jQuery。
如今有一些JavaScript來使IE模擬標準瀏覽器,若是你有較高比例的用戶使用IE6而且開啓了JavaScript,能夠考慮使用Dean Edwards的IE7或者相似的腳本。
譯者注:不建議使用這些腳本,由於這些「模擬」的實現每每會消耗大量的資源,IE原本就夠爛了。
在IE下調試頁面很麻煩,Firefox下的擴展程序Firebug和Web Developer Toolbar都是很好用的工具,若是你想在IE或其餘瀏覽器上使用firebug,能夠用Firebug Lite。
在IE下有兩種最好的調試方法:IE Collection和IETester,而且都是免費的(雖然有一點點缺陷)。IETester的開發者也提供了DebugBar這款IE插件免費供我的使用,但商業用戶只可試用60天。
兼容IE6的第一步就是單獨對IE進行兼容,你針對IE6所寫的代碼隻影響IE6;有幾種方法能夠區分開IE6:IE特有條件註釋、CSS選擇器、JavaScript,咱們將逐一討論。
微軟給IE添加了條件註釋以區分不一樣版本,任何東西均可以塞進條件註釋裏:標籤、JavaScript、js文件、css、內聯樣式。可使用條件註釋來針對某一個IE瀏覽器版原本編寫代碼。
規則以下:(譯註:可參考IE 特有註釋(hack))
<p>這段文字會在全部瀏覽器顯示p><!--[if lte IE 6]><p>這段文字僅顯示在 IE6及IE6如下版本。p><p>This message will only appear in versions of Internet Explorer less than or equal to version 6.p><![endif]--> <!--[if gte IE 6]><p>這段文字僅顯示在 IE6及IE6以上版本。p><p>This message will only appear in versions of Internet Explorer greater than or equal to version 6.p><![endif]--> <!--[if gt IE 6]><p>這段文字僅顯示在 IE6以上版本(不包含IE6)。p><p>This message will only appear in versions of Internet Explorer greater than version 6.p><![endif]--> <!--[if IE 5.5]><p>這段文字僅顯示在 IE5.5。p><p>This message will only appear in Internet Explorer 5.5.p><![endif]--> <!--在 IE6及IE6如下版本中加載css--><!--[if lte IE 6]><link type="text/css" rel="stylesheet" href="css/ie6.css" /><![endif]--> <p>這段文字會在全部瀏覽器顯示p>
使用條件註釋加載css的好處是這些樣式是獨立於其餘css文件的,所以不會在編寫兼容代碼時弄得一團糟;並且當IE6的市場份額下降到不須要兼容時,能夠快速的清理掉。
使用條件註釋的惟一缺點是在IE瀏覽器下會增長額外的HTTP請求數,因此須要權衡是否這樣作。但我不建議使用條件註釋加載外部js文件,由於js文件會形成阻滯,在js未加載完以前其他文件都不會被加載;對於js請使用JavaScript程序來區分瀏覽器而非條件註釋。
若是你不打算使用條件註釋,CSS選擇器是另一個區分開IE6的辦法,IE6不支持子選擇器;先針對IE6使用常規申明CSS選擇器,而後再用子選擇器針對IE7+及其餘瀏覽器。
示例:
<style type="text/css" >/* IE6 專用 */.content {color:red;}/* 其餘瀏覽器 */div>p .content {color:blue;}style><div><p class="header">Some Header Text Herep>div>
這個方法的缺點是容易把樣式表弄得一團糟,因此必定要寫好註釋說明。
在示例中,針對IE6寫的樣式在其餘瀏覽器中也會執行,但(標準瀏覽器中)以後的子選擇器覆蓋了以前的申明,而IE6不支持子選擇器因此忽略了它。
若是你想要使用JavaScript區分開IE6,請看示例:
//原生JavaScriptif(typeof document.body.style.maxHeight === "undefined") {alert('IE6 Detected');} //MooTools(框架)if (Browser.Engine.trident4) {alert('IE6 Detected');} //jQuery(框架)if (($.browser.msie) && ($.browser.version == "6.0")){alert('IE6 Detected');}
有不少JavaScript解決方案來修復IE6使用PNG-24圖片,但除了Twin Helix’s IE5.5+ PNG Alpha Fix都不支持CSS sprites。
另一個辦法是使用IE特有的濾鏡,可閱讀Aaron Baxter的博客。或譯者的《ie5+ PNG Fix》
能夠詳細閱讀CSS 圓角菜單。
若是你給連接、按鈕用CSS sprites做爲背景,你可能會發如今IE6下會有背景圖閃爍的現象。形成這個的緣由是因爲IE6沒有將背景圖緩存,每次觸發hover的時候都會從新加載,能夠用JavaScript設置IE6緩存這些圖片:
document.execCommand("BackgroundImageCache",false,true);
解決IE6佈局方面的BUG很是的惱人!特別是在實現一個精美的設計稿時。
許多IE6下的Bug及渲染問題均可以歸於微軟的私有概念hasLayout
。簡要的說,在給元素定義具體的尺寸(如height
或width
)就會觸發hasLayout
,在IE6下缺失或觸發hasLayout會致使一些bug。
若是怪異模式(quirks mode)在IE6中啓用,IE6將會使用微軟舊版的盒模型:width是元素的實際寬度,內容寬度 = width – (margin-left + margin-right + padding-left + padding-right + border-left-width + border-right-width)。最好的辦法是申明正確的文檔類型以免觸發怪異模式,或者避免給有border
或padding
的元素定義width
屬性。固然你也能夠考慮使用條件註釋。
IE6 不支持min-height
屬性,但它卻認爲height
就是最小高度。感謝Dustin Diaz提供了一個很好的方法:使用!important
,ie6會忽視它但其他瀏覽器不會。
注:IE6在同一個聲明語句中(即一個綜括號{}
)的屬性定義,後面的老是會覆蓋前面的,因此下例中後面的height覆蓋掉了前面定義的important height
/* 全部瀏覽器 */#container {min-height:200px; height:auto !important; height:200px;}
另外一個方法是使用CSS 選擇器:
/* 僅IE6 */#container {min-height:200px; height:200px;} /* 其餘瀏覽器 */html>body #container { height:auto;}
很是遺憾,在IE6下實現max-height
只能使用IE特有濾鏡,或者可使用JavaScript實現。我我的更建議使用JavaScript來解決,由於IE濾鏡會消耗大量資源甚至會使瀏覽器崩潰,並且禁用JavaScript後這兩種方法都沒法生效。
//直接使用ID來改變元素的最大高度var container = document.getElementById('container');container.style.height = (container.scrollHeight > 199) ? "200px" : "auto"; //寫成函數來運行function setMaxHeight(elementId, height){var container = document.getElementById(elementId);container.style.height = (container.scrollHeight > (height - 1)) ? height + "px" : "auto";} //函數示例setMaxHeight('container1', 200);setMaxHeight('container2', 500);
在IE6下,若是要給元素定義100%高度,必需要明肯定義它的父級元素的高度,若是你須要給元素定義滿屏的高度,就得先給html
和body
定義height:100%;
。
/* 給child元素定義100%高度(IE6)*/#parent {height:500px;}#child {height:100%;} /* 定義滿屏高度(IE6)*/html, body {height:100%;}#fullLength {height:100%;}
同max-height
和max-width
同樣,IE6也不支持min-width
。有2個方法實現最小寬度,使用額外的標籤、使用JavaScript。
//直接使用ID來改變元素的最小寬度var container = document.getElementById('container');container.style.width = (container.clientWidth < width) ? "500px" : "auto"; //寫成函數來運行function setMinWidth(elementId, width){var container = document.getElementById(elementId);container.style.width = (container.clientWidth < width) ? width + "px" : "auto";} //函數示例setMinWidth('container1', 200);setMinWidth('container2', 500);
只能使用JavaScript。
//直接使用ID來改變元素的最大寬度