想必你一定知道瀏覽器有個標(biāo)準(zhǔn)(Standards)模式和一個怪異(Quirks)模式,或許你還聽說過有個“準(zhǔn)標(biāo)準(zhǔn)(Almost Standards)”模式,。而當(dāng)你打開Internet Explorer的時候,,又看到了什么瀏覽器模式、文檔模式,,還有什么兼容性視圖等等...
這些都是什么,?啥是瀏覽器模式,啥是文檔模式,?標(biāo)準(zhǔn)模式和準(zhǔn)標(biāo)準(zhǔn)的模式有什么區(qū)別,?IE9兼容性視圖和真正的IE9有什么區(qū)別?什么情況下會觸發(fā)這些模式,,又該怎樣才能檢測到瀏覽器當(dāng)前處于哪種模式中呢,?本文將詳細(xì)為你解答這些疑問。
三種模式
首先我們要知道,為什么會有這么多模式,。其實這是個歷史遺留問題,,在瀏覽器大戰(zhàn)時期,網(wǎng)景瀏覽器(Netscape Navigator)和微軟的IE瀏覽器(Microsoft Internet Explorer)對網(wǎng)頁分別有不同的實現(xiàn)方式,,那個時候的網(wǎng)頁要針對這兩種瀏覽器分別開發(fā)不同的版本,。而到了W3C制定標(biāo)準(zhǔn)之后,這些瀏覽器就不能繼續(xù)使用這種頁面了,,因而會導(dǎo)致大部分現(xiàn)有站點都不能使用,。基于這個原因,,瀏覽器才引入兩種模式來處理一些遺留的站點,。
現(xiàn)在的瀏覽器排版引擎支持三種模式:怪異(Quirks)模式、準(zhǔn)標(biāo)準(zhǔn)(Almost Standards)和標(biāo)準(zhǔn)(Standards)模式,。在怪異模式中,,排版引擎會模擬 網(wǎng)景4和Windows中的IE5的行為;在完全標(biāo)準(zhǔn)的模式中,,會盡量執(zhí)行HTML和CSS規(guī)范所指定的行為,;而在準(zhǔn)標(biāo)準(zhǔn)模式中,則只包含很少的一部分怪異模式中的行為,。
那么所謂標(biāo)準(zhǔn)模式,,就一定都“標(biāo)準(zhǔn)”嗎?答案當(dāng)然是否定的,,因為各個瀏覽器廠商實現(xiàn)標(biāo)準(zhǔn)的階段不同,,所以各個瀏覽器的“標(biāo)準(zhǔn)模式”之間也會有很大的不同。
Firefox,、Safari,、Chrome、Opera (自 7.5 以后),、 IE8 和 IE9 都有一個準(zhǔn)標(biāo)準(zhǔn)模式,。那么既然標(biāo)準(zhǔn)模式都不那么標(biāo)準(zhǔn),準(zhǔn)標(biāo)準(zhǔn)的模式肯定就更不標(biāo)準(zhǔn)了,。最初的準(zhǔn)標(biāo)準(zhǔn)模式只會影響表格中的圖像,,而后來各個瀏覽器又或多或少地進行了修改。那么什么情況下會觸發(fā)準(zhǔn)標(biāo)準(zhǔn)模式呢,?是的,,正如你所想到的,某些DOCTYPE會觸發(fā)準(zhǔn)標(biāo)準(zhǔn)模式,,例如:
- "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "-//W3C//DTD XHTML 1.0 Frameset//EN"
- "-//W3C//DTD HTML 4.01 Transitional//EN"
- "-//W3C//DTD HTML 4.01 Frameset//EN"
- "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"
一個完整的 DOCTYPE 例子如下:
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
- "http://www./TR/html4/loose.dtd">
如果在Firefox中插入這種DOCTYPE,,并在頁面中插入一個空的span標(biāo)簽,那么在Firebug中查看元素的布局就會發(fā)現(xiàn)不同:
準(zhǔn)標(biāo)準(zhǔn)模式中元素的line-height被忽略了,元素既沒有寬度也沒有高度:
標(biāo)準(zhǔn)模式中元素仍然保留了line-height,,擁有18px的高度:
在Firefox瀏覽器中,,使用鼠標(biāo)右鍵->查看頁面信息 可以看到當(dāng)前瀏覽器運行在何種模式(只能看到“混雜模式”和“標(biāo)準(zhǔn)規(guī)范模式”兩種表示):
有位大神Henri Sivonen曾寫過一篇文章叫做Activating Browser Modes with Doctype,里面包含了一個完整的表格,,展示了各種DOCTYPE設(shè)置將會使瀏覽器以何種方式渲染。這里還有一篇秦歌的譯文《用doctype激活瀏覽器模式》,。
鑒于目前一些最新版本的瀏覽器已經(jīng)放棄了準(zhǔn)標(biāo)準(zhǔn)模式,,所以關(guān)于準(zhǔn)標(biāo)準(zhǔn)模式的細(xì)節(jié)這里就不再贅述了,感興趣的同學(xué)可以詳細(xì)閱讀以下資料:
那么,,既然這么多的DOCTYPE都會觸發(fā)非標(biāo)準(zhǔn)的模式,,那么如何才能觸發(fā)標(biāo)準(zhǔn)模式呢?對了,!要使用HTML5 DOCTYPE,,即:
- <!DOCTYPE html>
注意:如果文檔中沒有包含DOCTYPE或者包含了一個無法識別的DOCTYPE,則瀏覽器就會進入怪異模式,。
下面簡單說一下怪異模式,。怪異模式有許多“怪異”的行為,主要是為了兼容那些遺留的古老頁面而保留的模式,。不同瀏覽器的怪異模式也不盡相同,,它們都有自己的實現(xiàn)方式。怪異模式與標(biāo)準(zhǔn)模式的差異主要體現(xiàn)在 盒模型(box model),、表格單元格高度的處理等,。例如IE的怪異模式中,元素的width包含了padding和border,,而標(biāo)準(zhǔn)模式中padding和border 并不屬于寬度的一部分,。
若想詳細(xì)了解瀏覽器在怪異模式下的行為,可以參看下面兩篇文章,。不過不建議在這上面花太多的精力,,這是個歷史遺留問題,而且我們也盡量保證新開發(fā)的頁面不要進入到怪異模式:
小結(jié):至此我們需要了解,,瀏覽器有三種運行模式,,即標(biāo)準(zhǔn)模式、準(zhǔn)標(biāo)準(zhǔn)模式和怪異模式,,要使用 <!DOCTYPE html> 來正確地觸發(fā)標(biāo)準(zhǔn)模式,。千萬不要丟掉DOCTYPE聲明,因為這會導(dǎo)致瀏覽器進入怪異模式,。
IE的瀏覽器模式
IE8有4種模式:IE5.5怪異模式,、IE7標(biāo)準(zhǔn)模式、IE8準(zhǔn)標(biāo)準(zhǔn)模式和IE8標(biāo)準(zhǔn)模式,而IE9有7種模式: IE5.5怪異模式,、IE7標(biāo)準(zhǔn)模式,、IE8準(zhǔn)標(biāo)準(zhǔn)模式、IE8標(biāo)準(zhǔn)模式,、IE9準(zhǔn)標(biāo)準(zhǔn)模式,、IE9標(biāo)準(zhǔn)模式、XML模式,。
其中XML模式是針對XML文檔的,,這里不打算闡述,細(xì)節(jié)可以看這篇文章[Defining Document Compatibility](http://msdn.microsoft.com/en-us/library/cc288325(v=vs.85).aspx) 中有詳細(xì)闡述,。
在IE8及以后的的IE瀏覽器中,,支持X-UA-Compatible頭,可以通過在服務(wù)器端設(shè)置HTTP頭,,或者在頁面中插入<meta>標(biāo)簽來實現(xiàn):
- HTTP:
- Header set X-UA-Compatible "IE=8"
-
- Meta:
- <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
這種方法主要是防止老的頁面在較新的瀏覽器中顯示不正常的情況的,, 比如上面的代碼可以強制IE8以上版本的瀏覽器以IE7的模式進行渲染。
注意,,不要在新開發(fā)的網(wǎng)頁中使用這種技術(shù),,這種技術(shù)只應(yīng)該作為新老網(wǎng)頁更替過程中的過渡方案。由于目前新開發(fā)的網(wǎng)頁都是盡量支持最新版本的瀏覽器的,,所以這種技術(shù)也會慢慢被淘汰,,感興趣的同學(xué)可以詳細(xì)閱讀 微軟的這篇文檔。
小結(jié):這里我們需要知道有這種方式可以強制瀏覽器以某種模式運行,,但只應(yīng)作為過渡方案,,不應(yīng)在新開發(fā)的網(wǎng)頁中使用。
IE9兼容性視圖與IE9標(biāo)準(zhǔn)視圖
如果你使用的是IE9,,那么按下F12鍵就會出現(xiàn)開發(fā)者工具,,上面有兩個下拉菜單:瀏覽器模式和文檔模式。那么什么是瀏覽器模式,?什么又是文檔模式,?二者有何區(qū)別?
瀏覽器模式用于切換IE針對該網(wǎng)頁的默認(rèn)文檔模式,、對不同版本瀏覽器的條件注釋解析,、以及發(fā)送給網(wǎng)站服務(wù)器的用戶代理(User-Agent)字符串的值。網(wǎng)站可以根據(jù)瀏覽器返回的不同用戶代理字符串判斷瀏覽器的版本和及安裝的功能,,這樣就可以根據(jù)不同的瀏覽器返回不同的頁面內(nèi)容了,。
文檔模式用于指定IE的頁面排版引擎(Trident)以哪個版本的方式來解析并渲染網(wǎng)頁代碼。切換文檔模式會導(dǎo)致網(wǎng)頁被刷新,,但不會更改用戶代理字符串中的版本號,,也不會從服務(wù)器重新下載網(wǎng)頁,。切換瀏覽器模式的同時,瀏覽器也會自動切換到相應(yīng)的文檔模式,。
一言以蔽之,,瀏覽器模式會影響服務(wù)器端對客戶端瀏覽器版本的判斷,對條件注釋也有影響,;而文檔模式會影響IE的排版引擎,,對網(wǎng)頁渲染會有影響,對CSS hack也會產(chǎn)生影響,。因此,,通過條件注釋可以判斷瀏覽器模式,而使用CSS hack可以判斷文檔模式,。
如果我們使用一句簡單的JavaScript語句來查看用戶代理(User-Agent)字符串的值,則可以看到IE9兼容性視圖與IE9的區(qū)別:
- <script type="text/javascript">
- alert('UA:'+navigator.userAgent);
- </script>
輸出結(jié)果如下所示,,注意其中的MSIE版本號已經(jīng)不同,。判斷瀏覽器模式就是判斷User-Agent中的版本號,即MSIE后面的數(shù)值:
- // IE9
- UA:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0)
-
- // IE9 兼容性視圖
- UA:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0)
話說IE9兼容性視圖是模擬IE7的行為,,那么IE9兼容性視圖與IE7有沒有區(qū)別呢,?肯定是有區(qū)別的,即使是IE9中的IE7標(biāo)準(zhǔn)模式,,與原生的IE7在渲染上也是有區(qū)別的,,具體我們暫不去深究。
那么既然IE9兼容性視圖的版本號跟IE7相同,,如何才能判斷當(dāng)前是IE9兼容性視圖,,還是純正的IE7呢?其實很簡單,,只需要判斷瀏覽器的用戶代理(User-Agent)字符串中是否包含Trident即可,。首先檢測MSIE的版本號是否為7.0,然后再判斷是否含有Trident字串,,若包含則為IE9兼容性視圖,,否則則為純正的IE7。
小結(jié):至此,,你應(yīng)該了解了什么是瀏覽器模式,、什么是文檔模式以及它們之間的區(qū)別了,另外還了解了IE9兼容性視圖與IE9以及IE7的區(qū)別,。
控制默認(rèn)的渲染方式
當(dāng)Internet Explorer 9遇到未包含X-UA-Compatible標(biāo)頭的網(wǎng)頁時,,它將使用<!DOCTYPE>指令來確定如何顯示該網(wǎng)頁。 如果該指令丟失或未指定基于標(biāo)準(zhǔn)的文檔類型,,則Internet Explorer 9將以IE5模式(怪異模式)來顯示該網(wǎng)頁,。
如果<!DOCTYPE>指令指定了基于標(biāo)準(zhǔn)的文檔類型,,則Internet Explorer 9將以IE9模式顯示該網(wǎng)頁,但出現(xiàn)以下情況時除外:
- 為該網(wǎng)頁啟用了兼容性視圖,。
- 該網(wǎng)頁是在Intranet區(qū)域中加載的,,并且已將Internet Explorer 9配置為使用兼容性視圖來顯示Intranet區(qū)域中的網(wǎng)頁。
- 已將Internet Explorer 9配置為使用兼容性視圖來顯示所有網(wǎng)站,。
- 已將Internet Explorer 9配置為使用兼容性視圖列表(其實是個黑名單,,其中指定了一組始終使用兼容性視圖顯示的網(wǎng)站)。
- 已使用開發(fā)人員工具覆蓋在該網(wǎng)頁中指定的設(shè)置,。
- 該網(wǎng)頁遇到了頁面布局錯誤,,并且已將Internet Explorer 9配置為,通過在兼容性視圖中重新打開網(wǎng)頁來自動從此類錯誤中恢復(fù),。
此外,,可以使用下面的注冊表項來控制Internet Explorer對未包含X-UA-Compatible標(biāo)頭的頁面的處理方式。
- HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER)
- SOFTWARE
- Microsoft
- Internet Explorer
- Main
- FeatureControl
- FEATURE_BROWSER_EMULATION
- iexplore.exe = (DWORD)
其中DWORD值必須等于下列值之一:
值 說明
7000 包含基于標(biāo)準(zhǔn)的 <!DOCTYPE> 指令的頁面將以 IE7 模式顯示,。
8000 包含基于標(biāo)準(zhǔn)的 <!DOCTYPE> 指令的頁面以 IE8 模式顯示,。
8888 頁面始終以 IE8 模式顯示,而不考慮 <!DOCTYPE> 指令,。 (這可繞過前面列出的例外情況,。)
關(guān)于IE瀏覽器確定文檔模式的整個流程,可以參看這篇文章How IE8 Determines Document Mode,,文中詳細(xì)闡述了整個流程與內(nèi)部機制,。
小結(jié):仍然堅持使用<!DOCTYPE html>,可最大程度減小發(fā)生錯誤的幾率,。
文檔模式的檢測
在JavaScript中可以通過documentMode來檢測文檔模式,,在IE6和IE7中是使用compatMode來確定文檔模式的,這個屬性自IE8開始已經(jīng)被documentMode所替代,。
那么,,如果需要兼容IE6和IE7的話(必須的 ...),則相應(yīng)的檢測代碼大致如下:
- engine = null;
- if (window.navigator.appName == "Microsoft Internet Explorer")
- {
- // This is an IE browser. What mode is the engine in?
- if (document.documentMode) // IE8 or later
- engine = document.documentMode;
- else // IE 5-7
- {
- engine = 5; // Assume quirks mode unless proven otherwise
- if (document.compatMode)
- {
- if (document.compatMode == "CSS1Compat")
- engine = 7; // standards mode
- }
- // There is no test for IE6 standards mode because that mode
- // was replaced by IE7 standards mode; there is no emulation.
- }
- // the engine variable now contains the document compatibility mode.
- }
IE6和IE7中的compatMode有兩個可能的值“CSS1Compat”和“BackCompat ”,,分別對應(yīng)了IE6和IE7中的標(biāo)準(zhǔn)模式和怪異模式,。上面的代碼首先假定是怪異模式,然后再試圖推翻假設(shè),。這里沒有包含“IE6 標(biāo)準(zhǔn)模式”,,因為它已經(jīng)被IE7標(biāo)準(zhǔn)模式所替代,沒有模擬的情況,。
這里要注意,,不同的文檔模式對JavaScript也有一些影響,我們不必去深究不同文檔模式對JavaScript有何種不同影響,,只需要在編碼時進行特定的特性檢測即可,。
小結(jié):一般情況下是沒必要進行文檔模式檢測的,,對于樣式兼容我們可以寫CSS hack,而對于JavaScript來說,,則更加推薦特性檢測,,而不是檢測瀏覽器本身。
瀏覽器模式與文檔模式之間的關(guān)系
瀏覽器模式可以決定頁面默認(rèn)的文檔模式,,但文檔模式可能會受其他因素影響而改變,,如上文所述。如果瀏覽器模式與文檔模式設(shè)置不同的話,,會不會有什么影響呢,?
我們已經(jīng)知道瀏覽器模式主要用于標(biāo)識瀏覽器本身,原則上不會對頁面渲染產(chǎn)生影響,。但是我們又知道,,瀏覽器模式可以影響條件注釋,所以如果你的頁面中有條件注釋的話,,那么瀏覽器模式的變化就會影響到頁面渲染,。
服務(wù)器端只能通過瀏覽器模式所標(biāo)識的版本來確定客戶端瀏覽器的版本,如果你將瀏覽器模式標(biāo)識為IE9,,但文檔模式選擇為IE7標(biāo)準(zhǔn)的話,就可能會有問題,。不過這還要看服務(wù)器端是否有針對不同瀏覽器的處理策略,,如果服務(wù)器端并未對不同瀏覽器的輸出做差異化處理的話,那么這兩個模式選項不同就不會有問題,。
小結(jié):如果服務(wù)器端對不同瀏覽器的輸出做了差異化處理,,那么瀏覽器模式和文檔模式不一致就可能產(chǎn)生問題。
結(jié)語
本文參考了大量現(xiàn)有文獻,,詳細(xì)闡述了各種模式的區(qū)別以及它們之間的關(guān)系,。相信通過上面的敘述,你已經(jīng)能夠區(qū)分這些瀏覽器模式或者文檔模式以及它們之間的關(guān)系了,,每節(jié)的結(jié)論在小結(jié)中已有闡述,,希望能夠?qū)δ阌兴鶐椭?/p>
來自:圖靈社區(qū)