Web常用工具 二维码美化 在线压缩 JavaScript AI工具汇总网站 ASP.NET控件源码查询 W3CHTML W3SCHOOL TypeScript 开源中国 51aspx github codeproject SQLBACKUP 几种排序算法比较 SQL中deny权限 MSDN下载 HttpWebRequest类 HTML5 stackoverflow ASP.NET 页生命周期概述 IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述 [SQL Server]视图sys.sysprocesses brnshop学习 SQL视频 Fiddler帮助文档 Sprint.Net SQLServer牛人博客 codeplex IIS官网 IE11 Developer Jquery源码视频上 Jquery源码视频下 Jquery Bugs jquery.miaov.com 正则表达式 Jquery API 1.9 Service Broker Javascript Object中的方法讲解 Microsoft webcast 微信开发接口 ECMAScript5 Underscore Jquery Bugs SQL存储过程事务嵌套 官网SQL事务锁 2345天气插件 Json数据查看 C++ jquery-plugin-validate 博学谷(传智播客) Swift视频 IOS代码论坛 SWIFT设计模式 操作系统下载 AngularJS VueJS ASPNETCORE 前端题库 Node.js ASPNETCORE 腾讯课堂 SwiftUI SwiftUI疑问解答 ADO.NET SMO 数字化企业网 Unicode码查询 Redis使用文档 .NET 微服务:适用于容器化 .NET 应用程序的体系结构 .NETCore5.0微软官方文档 CSS3.0 在 ASP.NET Core 中配置 Windows 身份验证 Maven使用教程 Maven Repository Thymeleaf Thymeleaf中文CSDN Spring官方文档 Spring中文文档 SpringBoot SpringData SVG在线设计工具 SVG教程01 SVG教程02 fontawesome图标库 mybatis官网 mybatis-spring中文 mysql教程 python教程 python的scrapy教程01 python的scrapy教程02 VS开发python xpath教程 腾讯向量数据库教程 JSZip浏览器内存中创建文件与文件夹 axios的使用文档 SheetJS(JS操作excel)的使用文档 金蝶云星空学习成长

huaan011

 

IE (第二部分) 浏览器 中 关于浏览器模式和文本模式

判断真正的 IE 版本

很多 JS 框架都通过 UA 判断 IE 的版本。对于 IE6,这种做法没问题( IE6 没有浏览器模式的概念,也没有其它 IE 可以把浏览器模式改为 IE6;IE7 虽然也没有浏览器模式,但 IE8+ 可以把浏览器模式设置为 IE7 模式)。但是从 IE8 开始引入的浏览器模式会产生不同的 UA。例如,IE9 有这些:

如果仅通过 UA 中的「MSIE X.0」来判断,会得到 IE7~9 三种不同结果。

实际上,对于 IE8+,根据 UA 字符串只能确定当前是否是兼容性视图。因为兼容性视图的 UA 中,IE 版本和 Trident 版本不匹配。例如 UA 里同时有「MSIE 7.0」和「Trident/6.0」,说明浏览器模式肯定是 IE10兼容性。这是因为 IE8 才开始给 UA 加上 Trident 信息,而 Trident/6.0 是 IE10 所特有。

除此之外,上面 IE7 和 IE8 这两种浏览器模式,UA 和跟真正的 IE7 或 IE8 没有任何区别,根据 UA 完全没办法区分。甚至连 IE9 模式,我们也无法确认这是 IE9 浏览器的默认模式,还是 IE10 浏览器的 IE9 模式。

下面来看看文本模式,依然用 IE9 测试。选择不同的文本模式,documentMode 的值也不一样。

document.documentMode 这个 JS 属性是 IE8 引入的,对于 IE8+ 无论选择什么文本模式,这个属性都有值。而 IE6 和 IE7 下,这个属性是 undefined。根据这一点,可以结合 UA 判断出用户使用的是不是真正的 IE7:UA 包含 IE7 时,如果 documentMode 等于 undefined,就一定是真正的 IE7 浏览器。对于 IE8+,这种方法就力不从心。例如 IE10 在浏览器模式为 IE8,文本模式为 IE8标准 时,与真正的 IE8 比较,无论是 UA,还是 document.documentMode,都一模一样。

综上,我们可以通过检查 UA 中 Trident 版本和 IE 版本是否匹配,来判断浏览器是否工作在兼容性视图模式下。结合 document.documentMode,还可以判断出用户是否使用真正的 IE7 浏览器。

JScript 引擎版本号

JScript 是 IE 的 JS 引擎,IE 提供了一系列 JS 接口来获取它的 JScript 信息:

我用这些接口测试了 IE6~10,发现 JScript 的版本号只与浏览器有关,与浏览器的浏览器模式或文档模式无关。

忽略内部版本号,只关注前两个数字,我们会发现,从 IE9 把 JS 引擎换成 Chakra 开始,版本号的规律变了。令人欣慰的是,不同的 JScript 版本号对应着不同版本的浏览器,这对判断出真正的 IE 版本很有帮助。例如,要识别低于 IE8 的浏览器,下面这样写就可以了。

if(ScriptEngineMinorVersion() != 0 && ScriptEngineMinorVersion < 8) {
    //这是 IE8-
}

  实际上,IE 支持的条件编译功能中,有个表示 JScript 版本的条件编译变量,如下(完整的条件编译变量清单见这里):

<script type="text/javascript">
    /*@cc_on
        alert(@_jscript_version);
    @*/
</script>

  这个变量是「major.minor」格式的 JScript 版本号,跟使用 JS 接口获取到的版本号一致,也只取决于浏览器版本,不受浏览器模式和文本模式的影响。

 

文本模式对 JScript 没影响?

看完上一节,再看我之前写的这段:文本模式决定:1)排版引擎;2)JS引擎,有明显的矛盾。难道之前的结论有误?

实际上,JS 获取到的 JScript 版本号仅仅表示了当前浏览器自带的 JScript 引擎版本(例如 IE9 始终是 9.0,IE7 始终是 5.7),并不代表任何情况都可以使用这个版本 JS 引擎的所有功能,页面使用哪种版本的 JScript 引擎还是由页面的文本模式来决定。

例如,IE8 的 JScript 版本是 5.8,但是只有在文本模式等于 IE8标准 时才可以使用 JScript5.8 的功能,其它任何文本模式都会导致页面使用 JScript5.7。

举个例子,JScript5.8 增加了对 JSON 的支持,所以 IE8 支持原生 JSON 对象。但网上很多人问为什么在 IE8/9 下无法使用原生 JSON。一种可能是页面没写 DTD,导致页面进入了 IE5怪异 这种文本模式,进而启用了不支持原生 JSON 的 JScript5.7 导致的。

再举几个例子:[,].length 在 JScript9.0 之前是 2;[1,2,3].join(undefined) 在 JScript5.8 之前是"1undefined2undefined3"。把 IE9 的文本模式分别改成 IE9标准IE8标准 和 IE7标准,可以得到下表:

类似的例子还有很多。大部分情况下,页面使用的 JScript 引擎版本会随着文本模式的降低而退化,页面对 JS 的支持度也随之退化。但教主 franky 提供了一个「for in顺序」的反例:

var o = {1 : '0', 0 : '1'}; for(var i in o) { console.log(i); }

  

对于 IE9+ 浏览器,这行代码输出顺序始终是 0 1;对于 IE9 以下的浏览器,输出顺序都是 1 0,并不受文本模式的影响。关于这一点我没想到比较好的解释。

一些 DOM 相关的方法,如 document.querySelectorAll,在文本模式为 IE7标准IE5怪异 时不可用;addEventListener 在文本模式为 IE8标准IE7标准IE5怪异 时不可用。这说明 IE 浏览器对 DOM 的支持度也会随着文本模式的降低而退化。

但是一些 BOM 方法,却跟文本模式无关。例如 IE8 开始支持的 postMessage 和 localStorage,只要浏览器是 IE8+,无论什么文本模式,这两个功能都可用。IE9+ 支持的 window.performance,在 IE9+ 浏览器上,也始终可用,跟当前的文本模式无关。

小结下:随着文本模式的降低,页面上实际使用的 JScript 引擎会退化,一些高版本支持的语言特性不再可用(如 JSON),但 for in 的顺序问题似乎不会退化;DOM 相关功能也有相应的退化;但大部分 BOM 接口却不会退化(如 localStorage)。

总结

本文讨论的内容在各部分都小结过,最后只说一个结论:在解决 JS 兼容性问题时,一定要使用能力检测和特性检测。因为无论是从 UA 中得到的浏览器信息,还是从 JS 接口中获取到的 JScript 引擎版本,都非常不可靠。例如 UA 中包含 IE7,并不一定不支持 IE9+ 的 window.performace。也可能是 IE9 浏览器使用了 IE9兼容性视图,UA 确实会变成 IE7,文本模式为 IE7标准,但不影响对 window.performace 的支持。

另外,虽然 IE 的浏览器模式和文本模式非常复杂,组合起来有几十种情况,但大部分情况只能通过开发者工具来构造。例如 UA 中包含 IE9,实际上使用 JScript5.7 的情况(浏览器模式为 IE9,文本模式为 IE7标准),正常情况下不会出现。

 

来源:https://www.imququ.com/post/browser-mode-and-document-mode-in-ie-2.html

 

posted on 2015-01-23 16:28  华安  阅读(433)  评论(0编辑  收藏  举报

导航