浏览器兼容模式(转)

三种模式

首先我们要知道,为什么会有这么多模式。其实这是个历史遗留问题,在浏览器大战时期,网景浏览器(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">

那么,既然这么多的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. Meta:
  4. <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

这种方法主要是防止老的页面在较新的浏览器中显示不正常的情况的, 比如上面的代码可以强制IE8以上版本的浏览器以IE7的模式进行渲染。

注意,不要在新开发的网页中使用这种技术,这种技术只应该作为新老网页更替过程中的过渡方案。由于目前新开发的网页都是尽量支持最新版本的浏览器的,所以这种技术也会慢慢被淘汰,感兴趣的同学可以详细阅读 微软的这篇文档。

这里我们需要知道有这种方式可以强制浏览器以某种模式运行,但只应作为过渡方案,不应在新开发的网页中使用。

解决方案

  IE浏览器从IE8开始添加了兼容模式,开启后会以低版本的IE进行渲染。兼容模式有可能会导致网页显示出问题,如何禁止使用IE8兼容模式解析网页呢?在IE8以上版本的浏览器增加了一个X-UA-Compatible 头标记,用于为IE8指定不同的页面渲染模式。

于是我们通常在HTML中添加下列代码来使 IE 使用固定的渲染模式:

<meta http-equiv="X-UA-Compatible" content="IE=8"><!--以IE8模式渲染-->
    <meta http-equiv="X-UA-Compatible" content="IE=7"><!--以IE7模式渲染-->

这段代码分别表示开启IE8和IE7的标准渲染模式。所以我们如果在网页中加上了代码:

<meta http-equiv="X-UA-Compatible" content="IE=8" />

或者:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

,那么就设定要用IE8标准模式渲染网页,而不会使用兼容的模式。

还有一种情况,在IE8下只有不使用兼容模式页面才能显示正常,但是如果设定为IE8的
模式,在IE9中却会导致CSS3失效。看来,需要针对 IE8、IE9 分别 禁用兼容模式。怎么办呢?可以在后台判断浏览器版本,如果是IE8就输出
content="IE=8",如果是IE9就输出content="IE=9"。其实还可以单纯通过HTML来实现的,HTML代码如下:

<metahttp-equiv="X-UA-Compatible"content="IE=9; IE=8; IE=7; IE=EDGE">

其内容随著指定的页面模式而更改,当要模拟IE8时,指定IE=IE8,指定IE=5, IE=7, 或IE=8来选择其中一种兼容性模式。你也可以指定IE=edge来指示IE8使用它支持的最高模式。

经测试后完美解决了兼容模式问题,这样设置后IE中设置兼容模式的按钮也会消失,可以按F12打开“开发人员工具”来检查浏览器模式。

X-UA-compatible标头没有大小写之分。然而除了title元素及其他的meta元素之外,它必须出现在网页header节其它元素之前的位置。

如果我们使用一句简单的JavaScript语句来查看用户代理(User-Agent)字符串的值,则可以看到IE9兼容性视图与IE9的区别:

  • // 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

那么既然IE9兼容性视图的版本号跟IE7相同,如何才能判断当前是IE9兼容性视图,还是纯正的IE7呢?其实很简单,只需要判断浏览器的用户代理 (User-Agent)字符串中是否包含Trident即可。首先检测MSIE的版本号是否为7.0,然后再判断是否含有Trident字串,若包含则 为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.
  19. }

IE6和IE7中的compatMode有两个可能的值“CSS1Compat”和“BackCompat ”,分别对应了IE6和IE7中的标准模式和怪异模式。上面的代码首先假定是怪异模式,然后再试图推翻假设。这里没有包含“IE6 标准模式”,因为它已经被IE7标准模式所替代,没有模拟的情况。

这里要注意,不同的文档模式对JavaScript也有一些影响,我们不必去深究不同文档模式对JavaScript有何种不同影响,只需要在编码时进行特定的特性检测即可。

小结:一般情况下是没必要进行文档模式检测的,对于样式兼容我们可以写CSS hack,而对于JavaScript来说,则更加推荐特性检测,而不是检测浏览器本身。

浏览器模式与文档模式之间的关系

浏览器模式可以决定页面默认的文档模式,但文档模式可能会受其他因素影响而改变,如上文所述。如果浏览器模式与文档模式设置不同的话,会不会有什么影响呢?

我们已经知道浏览器模式主要用于标识浏览器本身,原则上不会对页面渲染产生影响。但是我们又知道,浏览器模式可以影响条件注释,所以如果你的页面中有条件注释的话,那么浏览器模式的变化就会影响到页面渲染。

服务器端只能通过浏览器模式所标识的版本来确定客户端浏览器的版本,如果你将浏览器模式标识为IE9,但文档模式选择为IE7标准的话,就可能会有 问题。不过这还要看服务器端是否有针对不同浏览器的处理策略,如果服务器端并未对不同浏览器的输出做差异化处理的话,那么这两个模式选项不同就不会有问 题。

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

参考: http://www.csdn.net/article/2012-10-22/2811049

时间: 2024-10-13 21:02:15

浏览器兼容模式(转)的相关文章

360浏览器兼容模式打开页面错误

今天发布系统之后,客户发现问题说360和傲游都打不开右下角提示的页面而IE8可以打开,右下角图:返回404错误.我回到座位上打开系统看了下,确实如此.我仔细想了下,我平时自己开发模式下就可以,但是为啥发布了就不行了.我仔细看了下我360浏览器.原来我用的都是极速模式,webkit内核.立马切换到兼容模式下,果然挂了.让我郁闷了..话说兼容模式下用的ie内核.自己本机怎么也装的ie8,咋就不行了呢. 我打开前端代码发现有这么一句话:parent.document.getElementById("m

QQ浏览器兼容模式问题

今天客户反馈有个问题,他说用360浏览器的兼容模式无法登陆系统,我试了可以,接着试了IE11,也可以,然后跟经理汇报,他说他用qq浏览器兼容模式就不可以,于是我试了,果然不可以... 问题是酱紫的:输入账号密码后,点击登录,密码和验证码就不见了..我很奇怪,之前都是点登录就直接登录,或是说密码错误,验证码错误之类的.他啥也没报,控制台也没报,验证码没刷新,所以我想就是点了没反应.. 于是百度了很多东西,百度出来了一句话:<meta http-equiv="X-UA-Compatible&q

Meta告知IE浏览器兼容模式

在html的head头内如下写法,节选自http://www.xingzai.org/html-note/meta-tag-usage-order.html: <!--x-ua-compatible(浏览器兼容模式) 仅对IE8+以效 告诉浏览器以什么版本的IE的兼容模式来显示网页 <meta http-equiv="X-UA-Compatible" content="IE=5" > <meta http-equiv="X-UA-C

QQ浏览器兼容模式下Cookie失效 导致的NetCore Cookie认证失效

最近在写NetCore项目采用的是NetCore的Cookie认证.结果偶然发现QQ浏览器登录不好用.这里先需要了解一下set-cookie中的SameSite属性  导致原因 首先Fiddler 4查看一下两次请求 第一次Post进行登录 返回302重定向到站点首页并带回Cookie (一切正常) 但是看第二条http请求,返回又是302 ,查看相关信息,请求时Cookie 根本没带入 到此基本知道整个登录失败是因为Cookie没有带入请求头. 解决方案: NetCore Cookie认证下如

360浏览器兼容模式无法弹出layer对话框问题

问题    Layer插件的提示框在极速模式下正常显示,但是兼容模式下不显示. 解决 360有俩模式(点击地址栏的闪电图标或者IE图标可以切换) 一个是基于Webkit内核的极速模式,一个是IE内核的兼容模式.     强制360以极速模式浏览网页,可以给此网页增加meta,强制360浏览器以极速模式解析此网页,而非IE兼容模式. <html><head><meta name="renderer" content="webkit">

360浏览器兼容模式默认显示ie最高版本

之前写完代码都会放在360浏览器里跑一边,基本没啥问题,因为设置的都是极速模式,极速模式内置的是webkit内核,后来测试人员测试了兼容模式,发现会出各种问题,打开控制台一看,“我的天呐”,默认的竟然是ie7,本人从事前端以来就没调过ie7的兼容性,这可如何是好,后来同事给了一段代码,可以把默认版本改成ie最高版本, <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 瞬间所有问题

浏览器兼容模式下,上传文件问题

//在浏览器的兼容模式下,页面没有上传图片的时候,file != null && file.Count > 0 && file[""] != null 是成立的.但file[""].FileName != ""是不成立的 if (file != null && file.Count > 0 && file["file"] != null &&a

360浏览器兼容模式 不能$.post (不是a 连接 onclick的问题!!)

最近发现一个360浏览器很蛋疼的事情,在兼容模式下 代码: <a href="#" onclick='doAudit(1)'>审核</a> 点击没有任何效果,试了所有浏览器都不会 于是以为是兼容模式会变成IE6 于是改成各种写法 <a href="javascript:void(0)" onclick='doAudit(1); return false;'>审核</a> 等等 发现没有任何作用 后来慢慢静下心,一段段注

360浏览器兼容模式,页面不能正常渲染

360急速模式都可以正常的渲染,但是切换到兼容模式,页面就不能正常的渲染了.分析原因: 因为360浏览器中包含了两个浏览器 一个是IE(Trident内核),即兼容模式,在使用网银时需要切换为兼容模式 一个是Chrome(Chrommium内核),即极速模式,普通浏览时使用 使用极速模式,就类似与用了360的高速内核,兼容性很好 是谷歌的内核. 而使用兼容模式,360的做法是保留了你的电脑里面本身的ie内核,倘若你的电脑浏览器是ie7 ,使用兼容模式,就相当于 是使用了ie7,同理,如果你的电脑