深入理解浏览器兼容性模式

2023-10-26

原文地址: http://www.csdn.net/article/2012-10-22/2811049-Understanding-the-browser-compatibility-
摘要:关于各种浏览器模式,网上已经有许多文档和资料了,但是很少有能够完全将几个概念阐述清楚的。大部分的资料稍显过时,有些内容可能已经不再适用了。本文中笔者将尽可能将几个概念阐述清楚,并去掉一些过时的内容,仅保留必要的干货。

想必你一定知道浏览器有个标准(Standards)模式和一个怪异(Quirks)模式,或许你还听说过有个“准标准(Almost Standards)”模式。而当你打开Internet Explorer的时候,又看到了什么浏览器模式、文档模式,还有什么兼容性视图等等...

这些都是什么?啥是浏览器模式,啥是文档模式?标准模式和准标准的模式有什么区别?IE9兼容性视图和真正的IE9有什么区别?什么情况下会触发这些模式,又该怎样才能检测到浏览器当前处于哪种模式中呢?本文将详细为你解答这些疑问。

三种模式

首先我们要知道,为什么会有这么多模式。其实这是个历史遗留问题,在浏览器大战时期,网景浏览器(Netscape Navigator)和微软的IE浏览器(Microsoft Internet Explorer)对网页分别有不同的实现方式,那个时候的网页要针对这两种浏览器分别开发不同的版本。而到了W3C制定标准之后,这些浏览器就不能继续使用这种页面了,因而会导致大部分现有站点都不能使用。基于这个原因,浏览器才引入两种模式来处理一些遗留的站点。

现在的浏览器排版引擎支持三种模式:怪异(Quirks)模式、准标准(Almost Standards)和标准(Standards)模式。在怪异模式中,排版引擎会模拟 网景4和Windows中的IE5的行为;在完全标准的模式中,会尽量执行HTML和CSS规范所指定的行为;而在准标准模式中,则只包含很少的一部分怪异模式中的行为。

那么所谓标准模式,就一定都“标准”吗?答案当然是否定的,因为各个浏览器厂商实现标准的阶段不同,所以各个浏览器的“标准模式”之间也会有很大的不同。

Firefox、Safari、Chrome、Opera (自 7.5 以后)、 IE8 和 IE9 都有一个准标准模式。那么既然标准模式都不那么标准,准标准的模式肯定就更不标准了。最初的准标准模式只会影响表格中的图像,而后来各个浏览器又或多或少地进行了修改。那么什么情况下会触发准标准模式呢?是的,正如你所想到的,某些DOCTYPE会触发准标准模式,例如:

  
  
  1. "-//W3C//DTD XHTML 1.0 Transitional//EN"  
  2. "-//W3C//DTD XHTML 1.0 Frameset//EN"  
  3. "-//W3C//DTD HTML 4.01 Transitional//EN"  
  4. "-//W3C//DTD HTML 4.01 Frameset//EN"  
  5. "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" 

一个完整的 DOCTYPE 例子如下:

  
  
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  
  2.                       "http://www.w3.org/TR/html4/loose.dtd"> 

如果在Firefox中插入这种DOCTYPE,并在页面中插入一个空的span标签,那么在Firebug中查看元素的布局就会发现不同:

准标准模式中元素的line-height被忽略了,元素既没有宽度也没有高度:

Almost Standards

标准模式中元素仍然保留了line-height,拥有18px的高度:

Standards

在Firefox浏览器中,使用鼠标右键->查看页面信息 可以看到当前浏览器运行在何种模式(只能看到“混杂模式”和“标准规范模式”两种表示):

mozilla-standard-mode

有位大神Henri Sivonen曾写过一篇文章叫做Activating Browser Modes with Doctype,里面包含了一个完整的表格,展示了各种DOCTYPE设置将会使浏览器以何种方式渲染。这里还有一篇秦歌的译文《用doctype激活浏览器模式》

鉴于目前一些最新版本的浏览器已经放弃了准标准模式,所以关于准标准模式的细节这里就不再赘述了,感兴趣的同学可以详细阅读以下资料:

那么,既然这么多的DOCTYPE都会触发非标准的模式,那么如何才能触发标准模式呢?对了!要使用HTML5 DOCTYPE,即:

  
  
  1. <!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>标签来实现:

  
  
  1. HTTP:  
  2. Header set X-UA-Compatible "IE=8"  
  3.  
  4. Meta:  
  5. <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的区别:

  
  
  1. <script type="text/javascript"> 
  2. alert('UA:'+navigator.userAgent);  
  3. </script> 

输出结果如下所示,注意其中的MSIE版本号已经不同。判断浏览器模式就是判断User-Agent中的版本号,即MSIE后面的数值:

  
  
  1. // IE9  
  2. 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)  
  3.  
  4. // IE9 兼容性视图  
  5. 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模式显示该网页,但出现以下情况时除外:

  • 为该网页启用了兼容性视图。
  • 该网页是在Intranet区域中加载的,并且已将Internet Explorer 9配置为使用兼容性视图来显示Intranet区域中的网页。
  • 已将Internet Explorer 9配置为使用兼容性视图来显示所有网站。
  • 已将Internet Explorer 9配置为使用兼容性视图列表(其实是个黑名单,其中指定了一组始终使用兼容性视图显示的网站)。
  • 已使用开发人员工具覆盖在该网页中指定的设置。
  • 该网页遇到了页面布局错误,并且已将Internet Explorer 9配置为,通过在兼容性视图中重新打开网页来自动从此类错误中恢复。

此外,可以使用下面的注册表项来控制Internet Explorer对未包含X-UA-Compatible标头的页面的处理方式。

  
  
  1. HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER)  
  2. SOFTWARE  
  3. Microsoft  
  4. Internet Explorer  
  5. Main  
  6. FeatureControl  
  7. FEATURE_BROWSER_EMULATION  
  8. 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的话(必须的 ...),则相应的检测代码大致如下:

  
  
  1. engine = null;  
  2. if (window.navigator.appName == "Microsoft Internet Explorer")  
  3. {  
  4. // This is an IE browser. What mode is the engine in?  
  5. if (document.documentMode) // IE8 or later  
  6. engine = document.documentMode;  
  7. else // IE 5-7  
  8. {  
  9. engine = 5; // Assume quirks mode unless proven otherwise  
  10. if (document.compatMode)  
  11. {  
  12. if (document.compatMode == "CSS1Compat")  
  13. engine = 7; // standards mode  
  14. }  
  15. // There is no test for IE6 standards mode because that mode  
  16. // was replaced by IE7 standards mode; there is no emulation.  
  17. }  
  18. // 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标准的话,就可能会有问题。不过这还要看服务器端是否有针对不同浏览器的处理策略,如果服务器端并未对不同浏览器的输出做差异化处理的话,那么这两个模式选项不同就不会有问题。

小结:如果服务器端对不同浏览器的输出做了差异化处理,那么浏览器模式和文档模式不一致就可能产生问题。

结语

本文参考了大量现有文献,详细阐述了各种模式的区别以及它们之间的关系。相信通过上面的叙述,你已经能够区分这些浏览器模式或者文档模式以及它们之间的关系了,每节的结论在小结中已有阐述,希望能够对你有所帮助。

来自:图灵社区


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解浏览器兼容性模式 的相关文章

随机推荐

  • Java基础-匿名内部类

    匿名内部类可以作为方法的实际参数进行传输
  • JavaScript 数组中常用的方法

    添加 push 数组末尾添加 unshift 数组首位添加 splice 1 0 新增内容 再指定位置插入 第二参数为0 表示新增 大于0 表示修改 删除 pop 删除末尾 shift 删除首位 slice 0 1 删除指定数据 不会改变原
  • 《计算机网络 第七版》读后感

    上大学时 计算机网络是必修的一门课程 讲课的老师是学校里很资深的一个教授 非常有耐心 尽管如此 如今的我还是把那些知识都丢的所剩无几了 其实在工作中 就算是普通的程序员 用到计算机网络的相关知识也不算少 比如 Socket 再比如 RTSP
  • FPN网络详解(知识点记录)

    FPN网络详解 特征图金字塔网络FPN Feature Pyramid Networks 是2017年提出的一种网络 FPN主要解决的是物体检测中的多尺度问题 通过简单的网络连接改变 在基本不增加原有模型计算量的情况下 大幅度提升了小物体检
  • matlab拟合函数参数,matlab怎么拟合函数参数?

    你让fx fitresult结果fx就不是函数 而是个cfit类型了 你可以这样做 把参数提取出来 可以用lsqcurvefit 函数或nlinfit 函数拟合 例如 x y 确定参数的初始值是比较繁琐的工作 一般可以用随机函数rand 来
  • 【English】现在完成时高频考点————去了某地考点

    English 现在完成时高频考点 相信很多人 总是忘记 have has been to have has been in have has gone to 这三兄弟的意思以及用法 那么我就带大家复习一下吧 Have Has been t
  • Zabbix设置邮件脚本报警

    搭建环境 CentOS 6 8 Zabbix 3 0 24 一 安装sendmail或者postfix 安装一种即可 yum y install sendmail 安装 service sendmail start 启动 chkconfig
  • 【Linux】“grep -v grep”命令的作用 + 为什么需要使用该命令

    一 简介 我们经常会在shell脚本中见到如下命令 ps ef grep test sever grep v grep wc l 各子命令其作用如下 ps ef 指令用来查询所有进程 grep test server 通过管道来过滤指定 t
  • 北京无线网络服务器,无线网络服务器地址是什么意思

    无线网络服务器地址是什么意思 内容精选 换一换 简介 本文将详细演示如何用Python爬取糗事百科的笑话段子内容 还会讲到爬虫的时候需要重点关注的点 Web抓取是从Internet提取数据的过程 这也称为网络收集或网络数据提取 Python
  • Burpsuite的安装和简单使用

    这个软件在官网上是收费软件 所以我是问同学找的破解版 如果是在官网上购买的可能有些差距 下图是进入破解版的页面 点击那个 run 设置burp的代理地址和端口 在浏览器中设置代理服务器 启动代理 即burpsuite 访问http burp
  • C# Task和异步方法

    ThreadPool中有若干数量的线程 当有任务需要处理时 会从线程池中获取一个空闲的线程来执行任务 任务执行完毕后线程不会销毁 而是被线程池回收以供后续任务使用 当线程池中所有的线程都被占用 又有新任务要处理时 线程池会新建一个线程来处理
  • Android Studio查看SQLite数据库数据

    Android Studio查看SQLite数据库数据 1 下载插件 Database Navigator 2 另存为到桌面 3 测试连接 4 查看连接后的数据
  • 特征值分解(Eigen Value Decomposition,EVD)、奇异值分解(Singular Value Decomposition,SVD)原理、公式推导及应用

    1 正交矩阵 正交变换 正交变换是保持图形形状和大小不变的几何变换 包含旋转 平移 轴对称及这些变换的复合形式 正交变换可以保持向量的长度和向量之间的角度不变 特别的 标准正交基经正交变换后仍为标准正交基 在有限维的空间中 正交变换在标准正
  • 持安科技孙维伯:零信任 业务与安全的最优解

    10月29日 由安在主办的2022超级CSO高峰论坛 暨数字安全最佳实践研讨会 在深圳圆满举行 围绕 零信任 业务与安全的最优解 主题 持安科技联合创始人孙维伯讲述了零信任如何兼顾企业的安全与效率 并通过持安科技7年来的甲方零信任落地实践经
  • 【leetcode】55-跳跃游戏【C/C++】

    题目如下 解题思路 方法一 首先想到的是从前向后遍历数组 根据当前元素的大小逐一选择跳跃位置 深度搜索 回溯 但是该方法对于大规模数组时间复杂度过高 因为其不存在剪枝的过程 会遍历整个数组的每一种可能 代码如下 class Solution
  • 轻量级报表开发工具Fastreport 6个平台的功能究竟有何区别?

    FastReport Net是适用于Windows Forms ASP NET MVC和 NET Core的全功能报表解决方案 它可以在Microsoft Visual Studio 2005 2019中使用 支持 Net Framewor
  • 通过XManager5连接Linux操作系统,安装Eclipse工具,进行代码开发、测试

    通过上面操作 就可以看到Linux系统的界面了 需要XManager5工具的 可以私信给我
  • 澳洲色情网浏览人数创新高 涉嫌破坏两性关系

    澳洲色情网浏览人数创新高 涉嫌破坏两性关系 more 澳洲上网浏览包含情色交友等色情网页的人数创新高 其中三分之一还是女性 据报道 这项从今年一至三月所做的调查还显示 超过三分之一上网的澳洲人 至少浏览过一次以上的色情网页 其中有将近两成还
  • 改进的Patchwork数字水印算法——C++实现

    Patchwork数字水印算法基础原理 Patchwork原意为一种用各种颜色和形状拼接成的布料 Patchwork算法最早由麻省理工学院研发 在空间域上通过大量的模式冗余来实现鲁棒的数字水印技术 期初多用于打印票据的防伪 基础原理 Pat
  • 深入理解浏览器兼容性模式

    原文地址 http www csdn net article 2012 10 22 2811049 Understanding the browser compatibility 摘要 关于各种浏览器模式 网上已经有许多文档和资料了 但是很