瀏覽器模式和文檔模式怎麼玩?

一、前言                                      

  從IE8開始引入了文檔兼容模式的概念,作爲開發人員的我們可以在開發人員工具中通過“瀏覽器模式”和“文檔模式”(IE11開始改爲“瀏覽器模式”改成更貼切的“用戶代理字符串”)品味一番,它的出現極大地方便了苦逼的前端攻城獅們適配各版本的IE,但jser們也不能完全信任它,因爲它只是提供儘可能的文檔模式模擬而已。

  本篇大部分內容來源於官方解說:http://msdn.microsoft.com/library/cc288325(v=vs.85).aspx,並儘量融入個人平常工作中踩過的坑加以闡述。

  注意:本文內容僅針對HTTP頭Content-Type字段爲text/html的html文檔作說明,而XML文檔不在本文的討論範圍之內。

 

二、什麼是瀏覽器模式?                               

   初看“瀏覽器模式”確實不明白啥意思,也許IE的工程師們也瞭解這詞的蹩腳,於是IE11索性就改名爲“用戶代理字符串”。現在大夥應該清楚這貨就是用來設置navigator.userAgent和navigator.appVersion的。

   它唯一需要注意的是,在不同的IE版本中,它與文檔模式的關係可不相同。

   IE89中,倘若瀏覽器模式被設置爲Internet Explorer7,那麼文檔模式的只能設置爲7,6,5;

   IE11中,用戶代理字符串設置和文檔模式可謂是沒有半毛錢關係。

 

三、什麼是文檔模式?                                

  對於以Webkit、Molliza等作爲內核的瀏覽器來說,DOM樹的解析、渲染,JS的API等主要與內核版本掛鉤;而對於IE瀏覽器而言,這些從IE6開始就跟文檔模式掛鉤了。爲了更好的理解文檔模式,我們以時間爲線從IE5.5開始學習吧!

  3.1. 從“久遠”的IE5.5說起

  現在雖然沒什麼用使用IE5.5了,但它卻從未離開過我們,因爲IE5.5一直以怪異模式(Quirks,IE5的文檔模式)的形式存活在我們的身邊。不過在那個只有IE5.5的年代,並沒有Quirks這一說法,只是後來IE6面世後逐漸向W3C標準靠攏,而IE5.5下DOM樹的解析、渲染等都與W3C標準有很大差別,於是命其名爲Quirks。

 

  3.2. 兼容模式——IE6的新發明

  由於IE6和IE5.5下DOM樹的解析等都有很大差異,導致那些適配IE5.5的老網站無法在IE6上正常顯示,於是出現了一個新功能——“兼容模式”,用於解決老網站的顯示問題。IE6的兼容模式就兩種,怪異模式(Quirks)和IE6標準模式。(IE7也只有怪異模式和IE7標準模式)

 IE6默認使用怪異模式(Quirks),僅當以<!DOCTYPE>作爲文檔第一行聲明文檔類型時,才採用IE6的標準模式,即使IE無法識別所聲明的文檔類型。(IE7也是這樣)

 注意:這時的兼容模式主要是解決顯示問題,要知道那時的JS只是小配角而已。

 

  3.3. 文檔兼容性模式——IE8的新寵

  “文檔兼容性模式”是對“兼容模式”的擴展,就IE8而言,除了提供怪異模式(Quirks)和IE8標準模式外,還提供了IE7標準模式、模擬IE7模式,而且設置的方式也豐富得多。

 

四、文檔模式的種類                               

  1. 怪異模式

    IE6789的是IE5.5的文檔模式,IE10+和Chrome等瀏覽器是W3C規範的怪異模式。

  2. 標準模式(非怪異模式)

    W3C標準的文檔模式,但各瀏覽器的實現階段不盡相同。

  3. 準標準模式(有限怪異模式)

    由於該模式離W3C標準仍然有一段距離,因此被稱作準標準模式(或有限怪異模式)。IE6、7的標準模式實際上就是準標準模式,而IE8+纔有實質上的標準模式。但到底兩者的不同點體驗在哪裏,本人暫時不瞭解,請各位指導!

 

五、IE8+設置文檔模式的方式                          

  開發者常用的方式:

  1. 開發者工具中的“文檔模式”;

  2. 通過在head標籤內加入如<meta http-equiv="X-UA-Compatible" content="IE=7">的元數據標籤(該例子將文檔模式設置爲IE7標準模式);

  3. 通過<!DOCTYPE>的增刪,在標準模式和怪異模式(Quirks)間切換;

  4. 通過Web服務器配置

IIS的web.config配置信息:


<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <clear />
        <add name="X-UA-Compatible" value="IE=EmulateIE7" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration> 

 

  用戶常用的方式:

  1. 點擊地址欄的兼容性視圖切換按鈕(僅當HTTP、HTTPS協議時纔出現該按鈕);

  2. 若網頁是在Intranet區域中加載,配置使用兼容性視圖顯示Intranet區域中的網頁;

  3. 配置瀏覽器使用兼容視圖瀏覽所有網頁;

  4. 將網站加入到兼容性視圖名單中;

  5. 內網管理員將該網站加入到兼容性視圖瀏覽名單中;

 

 微軟的方式:

  1. IE會定期向微軟官網拉數據,假如某網站被列入微軟的兼容性視圖瀏覽名單中,那麼就會IE就會以兼容性視圖模式來處理該網站。

 

   因此我們可以明白到文檔模式不是完全掌控在我們手中的,哎。。。。。。

 

六、<meta http-equiv="X-UA-Compatible">與<!DOCTYPE>結伴影響文檔模式    

  所有IE瀏覽器在默認情況下(<meta http-equiv="X-UA-Compatible">與<!DOCTYPE>均沒有),是採用怪異模式(Quirks);當有<!DOCTYPE>時,均採用瀏覽器版本對應的標準模式(如IE8就採用IE8標準模式,IE11就採用IE11標準模式)。

  現在要注意的是,當出現<meta http-equiv="X-UA-Compatible">時,文檔模式將會如何呢?我們首先了解一下IE11下它的content屬性值範圍吧,具體範圍如下:

  IE=5、IE=7、IE=EmulateIE7、IE=8、IE=EmulateIE8、IE=9、IE=10、 IE=11、 IE=Edge 

 1. IE=5:表示採用怪異模式;

 2. IE=7等純數字的值:表示採用對應IE版本的標準模式,即使不是以<!DOCTYPE>作爲文檔第一行,文檔模式依舊使用標準模式;

 3. IE=EmulateIE7等含EmulateIE字符串的值:表示採用模擬對應IE版本的模式,就是以<!DOCTYPE>作爲文檔第一行則採用標準模式,否則採用怪異模式。

 4. IE=Edge:表示採用瀏覽器自身版本的文檔模式,如IE11,以<!DOCTYPE html>作爲文檔第一行則採用IE11標準模式,否則採用怪異模式。

 

注意:

  1. 在IE11中,IE=10和IE=EmulateIE10是一樣的,IE=11、IE=EmulateIE11和IE=Edge是一樣的;

  2. 10及以上的文檔模式,若文檔第一行不是有效的<!DOCTYPE>(怎樣纔是有效的<!DOCTYPE>,請期待《JS魔法堂:doctype我們應該瞭解的基礎知識》),則document.compatMode返回BackCompat,但document.documentMode卻返回正確的文檔模式;

  3. 9及以下的文檔模式,只要文檔第一行出現<!DOCTYPE>,不管是否有效,document.compatMode均返回CSS1Compat。當文檔第一行沒有<!DOCTYPE>且沒有指定標準模式時,document.compatMode才返回BackCompat,且document.documentMode必定返回5。

 

七、對<meta http-equiv="X-UA-Compatible">瞭解多一點            

  6.1. 有效位置

    必須放在head標籤內纔有效。

  6.2. 多個標籤時只認第一個


<html>
    <head>
      <meta http-equiv="X-UA-Compatible" content="IE=7">
      <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
    </head>
    <body></body>
    <script type="text/javascript">
        console.log(document.documentMode); // 輸出 7
    </script>
</html>

  6.3. 無效content值,就設置爲最接近的文檔模式

    IE=a:文檔模式爲5

       IE=7.5:文檔模式7

  6.4. 一個標籤設置多個文檔模式,瀏覽器會自動選擇可用的最高的文檔模式


<html>
    <head>
      <meta http-equiv="X-UA-Compatible" content="IE=7;IE=9;IE=8">
    </head>
    <body></body>
    <script type="text/javascript">
        console.log(document.documentMode); // IE11中,輸出 9
    </script>
</html>

 

八、不一樣的標準模式                                

  雖然說IE6、7、8、9、10、11均有標準模式,但由於W3C標準規範內容隨時間的增改,而且瀏覽器對標準的實現是階段性的,因此個版本的標準模式不盡相同。

 

九、不一樣的怪異模式                                

  IE6789的怪異模式其實就是IE5.5的文檔模式,但從IE10開始它的遵守了W3C規範的怪異模式。所以大家不要被名字而矇騙咯!

舉個栗子:


<html>
  <head>
     <style type="text/css">
       #target{
           width: 100px;
           height: 20px;
           border: solid 1px red;
           margin: 0 auto;
       }
     </style>
  </head>
  <body>
       <div id="target"><div>
  </body>
</html>

  上面的代碼在是運行在怪異模式下,在IE6789下若要div#target自動水平居中,必須加上<!DOCTYPE html>轉成用標準模式渲染纔行。但在IE10+、Webkit和Molliza中即使在怪異模式下div#target也會自動水平居中。

 

十、文檔模式影響到哪些方面                              

  1. 佈局

  表格、單元格的樣式等都受到文檔模式的影響,尤其是盒子模型。

  2. 解析

  css和html的解析也會受到文檔模式的影響,就像在IE678標準模式時,HTML解析時會將嵌套form下的子節點挪到上一節;而IE9標準模式時不會。

  3. 腳本

  這個我想不用多說大家也深有體驗了。

 

十一、Jser別太開心                                  

  初次發現IE8+提供文檔兼容性模式時真的欣喜若狂,終於不用找機器來IE678逐個測試了,終於不用那個經常掛死的IETester了。但後來才發現文檔兼容性模式僅僅是方便我們開發調試而已,並不能完全替代IETester,更不能替代在真實的IE67上測試。因爲除了瀏覽器版本對應的文檔模式外,其他文檔模式均是跑在瀏覽器內核虛擬機上,而這些虛擬機僅僅能模擬真實瀏覽器內核的大部分DOM樹解析、渲染和JS API而已。例如在IE8上設定文檔模式爲怪異模式,但XMLHttpRequest依舊可用(XMLHttpRequest是從IE7開始纔有的),因此在檢測瀏覽器特性的時候,特徵嗅探比判斷瀏覽器的文檔模式更爲準確、好用。

  另外,從第六大點的注意事項中我們可以看到,從IE10開始IE要脫離IE56789的風格,真正靠近W3C標準。

  1. 沒有有效的doctype時盒子模型的渲染模式就是怪異模式,否則就使用標準模式;

  2. 盒子模型的渲染模式和文檔模式分離,也就是渲染模式爲怪異模式時,文檔模式不是5。這樣Jser還是使用IE10+的JS API,不用忍受IE5之苦;

  3. 雖然在document.compatMode爲BackCompat時,渲染模式都叫怪異模式,但IE56789的怪異模式和IE10+的怪異模式所顯示的效果和通過JS獲取的樣式數據都不同,IE10+的與Webkit、Molliza的效果相近。

  

 

十二、總結                                      

  從“瀏覽器模式”與“文檔模式”關聯,“文檔模式”與“盒子模型的渲染模式”掛鉤,到IE10+一下子將三者關聯切斷,轉向W3C標準。一直覺得IE9是IE非標準與標準間的過渡帶,現在就更加認定是這樣了。

  也許大家看到這裏會更加疑惑,似乎瞭解上述內容會加重開發的負擔(考慮的點更多了)。

  其實我們只要再次明確一下“文檔兼容性模式”的目的就好了,對終端用戶來講它是爲了在新版IE中儘量正確地顯示老網站;對開發者來講它是爲了方便調試新網站在舊版IE上的顯示效果和JS的有效性,極端情況下會通過鎖定文檔模式來啓用舊技術(如ie67下的vml)。

  所以作爲普通開發者的我們只需做三件事:

  1. 以有效的doctype作爲文檔的第一行,保證渲染模式爲標準模式;

  2. 開發前設定網站的最佳運行環境範圍,就是需適配的IE版本號,是否適配Webkit等;

  3. 開發並使用各種hacks爲兼容性付出不懈的努力。

  另外我曾參與一個項目需要運用VML來畫圖,客戶大部分使用IE678,少部分使用IE910,其他瀏覽器的可忽略不計,於是就可以通過鎖定文檔模式爲模擬IE7標準模式來啓用VML支持了。(官方聲IE9+不支持VML,但實際上IE8已經不支持了。)

 

  若作爲庫或框架開發者,由於文檔模式影響大部分JS API,而渲染模式影響各項樣式值和獲取方式等等,情況會複雜得多。因此綜合文檔模式判斷、特徵嗅探、渲染模式判斷是必須的,上述內容只是挖坑而已。

 文件頭聲明方式不一樣效果也是不一樣的,推薦把

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
改爲
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "w3.org/TR/html4/strict.dtd">

就不會出現Quirks Model了


原文地址:http://www.cnblogs.com/fsjohnhuang/p/3817418.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章