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
IE (第二部分) 浏览器 中 关于浏览器模式和文本模式的更多相关文章
- IE (第一部分) 浏览器 中 关于浏览器模式和文本模式的困惑
什么是浏览器模式和文本模式? 经常使用IE开发者工具的同学,肯定见过浏览器模式和文本模式,对于这两个名词,综合相关文档解释如下: 浏览器模式(Browser Mode),用于切换IE针对该网页的默认文 ...
- IE的浏览器模式、文本模式
最近在部署网页的时候,发现IE下的布局完成混乱. 在改变IE的文本模式后,显示就正常了. IE的浏览器模式,用于切换IE针对该网页的默认文本模式.对不同版本浏览器的条件注释解析.决定请求头里userA ...
- Windows 配置Apache以便在浏览器中运行Python script的CGI模式
打开httpd.conf,找到”#ScriptInterpreterSource Registry “,移除前面的注释# (如果找不到这行,就自己添加进去) 找到“Options Indexes Fo ...
- IE8"开发人员工具"使用详解下(浏览器模式、文本模式、JavaScript调试、探查器)
来源: http://www.cnblogs.com/JustinYoung/archive/2009/04/03/kaifarenyuangongju2.html 在上一篇文章IE8“开发人员工具” ...
- Linux的图形模式和文本模式以及单用户模式切换
1.默认开机进入文本模式 如果想让开机自动进纯文本模式, 修改/etc/inittab 找到其中的 id:5:initdefault: 这行指示启动时的运行级是5,也就是图形模式 改成3就是文本模式了 ...
- 浏览器中的user-agent的几种模式
服务器一般会根据访问的浏览器进行识别,针对不同浏览器才用不同的网站样式及结构,也是通过这个信息判断用户使用的平台模式(手机,pc或平板) 识别为手机一般有这几个关键字: "Windows P ...
- 第十一章:WEB浏览器中的javascript
客户端javascript涵盖在本系列的第二部分第10章,主要讲解javascript是如何在web浏览器中实现的,这些章节介绍了大量的脚本宿主对象,这些对象可以表示浏览器窗口.文档树的内容.这些章节 ...
- 权威指南学习心得-浏览器中的js
window对象:表示web了浏览器的一个窗口或窗体(winow属性引用自身) 含有以下属性:location包含Location对象,指定当前显示在窗口中URL,允许脚本往窗口里载入新的URL 含有 ...
- JavaScript权威指南--WEB浏览器中的javascript
知识要点 1.客户端javascript window对象是所有客户端javascript特性和API的主要接入点.它表示web浏览器的一个窗口或窗体,并且可以用window表示来引用它.window ...
随机推荐
- 我的常用笔记(GetAndroid,ADBDemo,GetSJ,GetTB)
一.授权相关格式(GetAndroid,ADBDemo,GetTB,GetSJ) [Mac]ID=0, Mac=9918D2A363, EndTime=2018-12-30 15:45: ...
- DateTimepicker中的星期问题
开发机:win10 64+VS2013 客户机:win7 32bit 在项目中使用DateTimepicker,需要将时间获取到,然后转换为string,然后再转换为DateTime类型.开发机器上测 ...
- 限制EditText最多输入n位,设置EditText最大输入长度;
1.比较笨的方法: /** * 设置edittext最大的输入限制 * @param editText * @param length */ private void setMaxLength(Edi ...
- 2013年第四届蓝桥杯JavaB组省赛试题解析
题目及解析如下: 题目大致介绍: 第一题到第四题是结果填空,方法不限只要得到最后结果就行 第五题和第六题是代码填空题,主要考察算法基本功和编程基本功 第七题到第十题是编程题,要求编程解决问题 第一题 ...
- SQL server 数据库的数据完整性
存储在数据库中的所有数据值均正确的状态.如果数据库中存储有不正确的数据值,则该数据库称为已丧失数据完整性. 详细释义 数据库中的数据是从外界输入的,而数据的输入由于种种原因,会发生输入无效或 错误信息 ...
- java中六个时间类的使用和区别
java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp java.text.SimpleDateFormat java.ut ...
- BZOJ2054 疯狂的馒头 并查集
题意:懒得写了有空再补上 链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2054 离线从后往前做,并查集维护下一个没染色的就可以啦- #incl ...
- Python的字典类型
Python的字典类型为dict,用{}来表示,字典存放键值对数据,每个键值对用:号分隔,每个键值对之间用,号分隔,其基本格式如下: d = {key1 : value1, key2 : value2 ...
- 阿里Canal配置(编写中)
首先在源mysql的.ini文件中进行配置 [client]default-character-set=utf8 [mysqld]basedir = E:/testCanal/mysql-5.7.17 ...
- 禁用firefox 56自动更新
firefox 56支持旧式扩展,这很重要! 它却自动更新,简单地关了也不行,很是牛氓! ========== -备份C:\Users\用户名\AppData\Roaming\Mozilla\Fire ...