摘要:关于各类浏览器模式,网上已经有许多文档和资料了,可是不多有可以彻底将几个概念阐述清楚的。大部分的资料稍显过期,有些内容可能已经再也不适用了。本文中笔者将尽量将几个概念阐述清楚,并去掉一些过期的内容,仅保留必要的干货。 javascript
想必你必定知道浏览器有个标准(Standards)模式和一个怪异(Quirks)模式,或许你还据说过有个“准标准(Almost Standards)”模式。而当你打开Internet Explorer的时候,又看到了什么浏览器模式、文档模式,还有什么兼容性视图等等... css
这些都是什么?啥是浏览器模式,啥是文档模式?标准模式和准标准的模式有什么区别?IE9兼容性视图和真正的IE9有什么区别?什么状况下会触发这些模式,又该怎样才能检测到浏览器当前处于哪一种模式中呢?本文将详细为你解答这些疑问。 html
三种模式 html5
首先咱们要知道,为何会有这么多模式。其实这是个历史遗留问题,在浏览器大战时期,网景浏览器(Netscape Navigator)和微软的IE浏览器(Microsoft Internet Explorer)对网页分别有不一样的实现方式,那个时候的网页要针对这两种浏览器分别开发不一样的版本。而到了W3C制定标准以后,这些浏览器就不能继续使用这种页面了,于是会致使大部分现有站点都不能使用。基于这个缘由,浏览器才引入两种模式来处理一些遗留的站点。 java
如今的浏览器排版引擎支持三种模式:怪异(Quirks)模式、准标准(Almost Standards)和标准(Standards)模式。在怪异模式中,排版引擎会模拟 网景4和Windows中的IE5的行为;在彻底标准的模式中,会尽可能执行HTML和CSS规范所指定的行为;而在准标准模式中,则只包含不多的一部分怪异模式中的行为。 web
那么所谓标准模式,就必定都“标准”吗?答案固然是否认的,由于各个浏览器厂商实现标准的阶段不一样,因此各个浏览器的“标准模式”之间也会有很大的不一样。 浏览器
Firefox、Safari、Chrome、Opera (自 7.5 之后)、 IE8 和 IE9 都有一个准标准模式。那么既然标准模式都不那么标准,准标准的模式确定就更不标准了。最初的准标准模式只会影响表格中的图像,然后来各个浏览器又或多或少地进行了修改。那么什么状况下会触发准标准模式呢?是的,正如你所想到的,某些DOCTYPE会触发准标准模式,例如:服务器
"-//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 例子以下: app
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
若是在Firefox中插入这种DOCTYPE,并在页面中插入一个空的span标签,那么在Firebug中查看元素的布局就会发现不一样: less
准标准模式中元素的line-height被忽略了,元素既没有宽度也没有高度:
标准模式中元素仍然保留了line-height,拥有18px的高度:
在Firefox浏览器中,使用鼠标右键->查看页面信息 能够看到当前浏览器运行在何种模式(只能看到“混杂模式”和“标准规范模式”两种表示):
有位大神Henri Sivonen曾写过一篇文章叫作Activating Browser Modes with Doctype,里面包含了一个完整的表格,展现了各类DOCTYPE设置将会使浏览器以何种方式渲染。这里还有一篇秦歌的译文《用doctype激活浏览器模式》。
鉴于目前一些最新版本的浏览器已经放弃了准标准模式,因此关于准标准模式的细节这里就再也不赘述了,感兴趣的同窗能够详细阅读如下资料:
那么,既然这么多的DOCTYPE都会触发非标准的模式,那么如何才能触发标准模式呢?对了!要使用HTML5 DOCTYPE,即:
<!DOCTYPE html>
注意:若是文档中没有包含DOCTYPE或者包含了一个没法识别的DOCTYPE,则浏览器就会进入怪异模式。
下面简单说一下怪异模式。怪异模式有许多“怪异”的行为,主要是为了兼容那些遗留的古老页面而保留的模式。不一样浏览器的怪异模式也不尽相同,它们都有本身的实现方式。怪异模式与标准模式的差别主要体如今 盒模型(box model)、表格单元格高度的处理等。例如IE的怪异模式中,元素的width包含了padding和border,而标准模式中padding和 border 并不属于宽度的一部分。
若想详细了解浏览器在怪异模式下的行为,能够参看下面两篇文章。不过不建议在这上面花太多的精力,这是个历史遗留问题,并且咱们也尽可能保证新开发的页面不要进入到怪异模式:
小结:至此咱们须要了解,浏览器有三种运行模式,即标准模式、准标准模式和怪异模式,要使用 <!DOCTYPE html> 来正确地触发标准模式。千万不要丢掉DOCTYPE声明,由于这会致使浏览器进入怪异模式。
IE的浏览器模式
IE8有4种模式:IE5.5怪异模式、IE7标准模式、IE8准标准模式和IE8标准模式,而IE9有7种模式: IE5.5怪异模式、IE7标准模式、IE8准标准模式、IE8标准模式、IE9准标准模式、IE9标准模式、XML模式。
其中XML模式是针对XML文档的,这里不打算阐述,细节能够看这篇文章[Defining Document Compatibility](http://msdn.microsoft.com/en-us/library/cc288325(v=vs.85).aspx) 中有详细阐述。
在IE8及之后的的IE浏览器中,支持X-UA-Compatible头,能够经过在服务器端设置HTTP头,或者在页面中插入<meta>标签来实现:
- HTTP:
- Header set X-UA-Compatible "IE=8"
- Meta:
- <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
这种方法主要是防止老的页面在较新的浏览器中显示不正常的状况的, 好比上面的代码能够强制IE8以上版本的浏览器以IE7的模式进行渲染。
注意,不要在新开发的网页中使用这种技术,这种技术只应该做为新老网页更替过程当中的过渡方案。因为目前新开发的网页都是尽可能支持最新版本的浏览器的,因此这种技术也会慢慢被淘汰,感兴趣的同窗能够详细阅读 微软的这篇文档。
小结:这里咱们须要知道有这种方式能够强制浏览器以某种模式运行,但只应做为过渡方案,不该在新开发的网页中使用。
IE9兼容性视图与IE9标准视图
若是你使用的是IE9,那么按下F12键就会出现开发者工具,上面有两个下拉菜单:浏览器模式和文档模式。那么什么是浏览器模式?什么又是文档模式?两者有何区别?
浏览器模式用于切换IE针对该网页的默认文档模式、对不一样版本浏览器的条件注释解析、以及发送给网站服务器的用户代理(User-Agent)字符串的值。网站能够根据浏览器返回的不一样用户代理字符串判断浏览器的版本和及安装的功能,这样就能够根据不一样的浏览器返回不一样的页面内容了。
文档模式用于指定IE的页面排版引擎(Trident)以哪一个版本的方式来解析并渲染网页代码。切换文档模式会致使网页被刷新,但不会更改用户代理字符串中的版本号,也不会从服务器从新下载网页。切换浏览器模式的同时,浏览器也会自动切换到相应的文档模式。
一言以蔽之,浏览器模式会影响服务器端对客户端浏览器版本的判断,对条件注释也有影响;而文档模式会影响IE的排版引擎,对网页渲染会有影响,对CSS hack也会产生影响。所以,经过条件注释能够判断浏览器模式,而使用CSS hack能够判断文档模式。
若是咱们使用一句简单的JavaScript语句来查看用户代理(User-Agent)字符串的值,则能够看到IE9兼容性视图与IE9的区别:
<script type="text/javascript">alert('UA:'+navigator.userAgent);</script>
输出结果以下所示,注意其中的MSIE版本号已经不一样。判断浏览器模式就是判断User-Agent中的版本号,即MSIE后面的数值:
- // 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有没有区别呢?确定是有区别的,即便是IE9中的IE7标准模式,与原生的IE7在渲染上也是有区别的,具体咱们暂不去深究。
那么既然IE9兼容性视图的版本号跟IE7相同,如何才能判断当前是IE9兼容性视图,仍是纯正的IE7呢?其实很简单,只须要判断浏览器的用户代理(User-Agent)字符串中是否包含Trident便可。首先检测MSIE的版本号是否为7.0,而后再判断是否含有Trident字串,若包含则为IE9兼容性视图,不然则为纯正的IE7。
小结:至此,你应该了解了什么是浏览器模式、什么是文档模式以及它们之间的区别了,另外还了解了IE9兼容性视图与IE9以及IE7的区别。
控制默认的渲染方式
当Internet Explorer 9遇到未包含X-UA-Compatible标头的网页时,它将使用<!DOCTYPE>指令来肯定如何显示该网页。 若是该指令丢失或未指定基于标准的文档类型,则Internet Explorer 9将以IE5模式(怪异模式)来显示该网页。
若是<!DOCTYPE>指令指定了基于标准的文档类型,则Internet Explorer 9将以IE9模式显示该网页,但出现如下状况时除外:
此外,可使用下面的注册表项来控制Internet Explorer对未包含X-UA-Compatible标头的页面的处理方式。
HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER) SOFTWARE Microsoft Internet Explorer Main FeatureControl FEATURE_BROWSER_EMULATION iexplore.exe = (DWORD)
其中DWORD值必须等于下列值之一:
值 说明
7000 包含基于标准的 <!DOCTYPE> 指令的页面将以 IE7 模式显示。
8000 包含基于标准的 <!DOCTYPE> 指令的页面以 IE8 模式显示。
8888 页面始终以 IE8 模式显示,而不考虑 <!DOCTYPE> 指令。 (这可绕过前面列出的例外状况。)
关于IE浏览器肯定文档模式的整个流程,能够参看这篇文章How IE8 Determines Document Mode,文中详细阐述了整个流程与内部机制。
小结:仍然坚持使用<!DOCTYPE html>,可最大程度减少发生错误的概率。
文档模式的检测
在JavaScript中能够经过documentMode来检测文档模式,在IE6和IE7中是使用compatMode来肯定文档模式的,这个属性自IE8开始已经被documentMode所替代。
那么,若是须要兼容IE6和IE7的话(必须的 ...),则相应的检测代码大体以下:
- 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 ”,分别对应了IE6和IE7中的标准模式和怪异模式。上面的代码首先假定是怪异模式,而后再试图推翻假设。这里没有包含“IE6 标准模式”,由于它已经被IE7标准模式所替代,没有模拟的状况。
这里要注意,不一样的文档模式对JavaScript也有一些影响,咱们没必要去深究不一样文档模式对JavaScript有何种不一样影响,只须要在编码时进行特定的特性检测便可。
小结:通常状况下是不必进行文档模式检测的,对于样式兼容咱们能够写CSS hack,而对于JavaScript来讲,则更加推荐特性检测,而不是检测浏览器自己。
浏览器模式与文档模式之间的关系
浏览器模式能够决定页面默认的文档模式,但文档模式可能会受其余因素影响而改变,如上文所述。若是浏览器模式与文档模式设置不一样的话,会不会有什么影响呢?
咱们已经知道浏览器模式主要用于标识浏览器自己,原则上不会对页面渲染产生影响。可是咱们又知道,浏览器模式能够影响条件注释,因此若是你的页面中有条件注释的话,那么浏览器模式的变化就会影响到页面渲染。
服务器端只能经过浏览器模式所标识的版原本肯定客户端浏览器的版本,若是你将浏览器模式标识为IE9,但文档模式选择为IE7标准的话,就可能会有问题。不过这还要看服务器端是否有针对不一样浏览器的处理策略,若是服务器端并未对不一样浏览器的输出作差别化处理的话,那么这两个模式选项不一样就不会有问题。
小结:若是服务器端对不一样浏览器的输出作了差别化处理,那么浏览器模式和文档模式不一致就可能产生问题。
结语
本文参考了大量现有文献,详细阐述了各类模式的区别以及它们之间的关系。相信经过上面的叙述,你已经可以区分这些浏览器模式或者文档模式以及它们之间的关系了,每节的结论在小结中已有阐述,但愿可以对你有所帮助。
来自:图灵社区