这种新式的技术最先由jQuery搞出来的,接着Prototype与mootools都支持了。这技术兴起的原因是浏览器嗅探技术是不太可靠,如UserAgent很容易被伪造,如IE8的UserAgent就把许多浏览器的关键字包含进去,造成辩识困难。其他一些重要辩识手段,由于浏览器厂商对旧版本的升级与不断推进新版本,许多都无效了。由于浏览器种类越来越多,版本也越来越多,看看Ext的核心文件吧,真是有耐性,连火狐与苹果的各个版本都列出来,这东西会没有止境地膨胀,为此特征侦测技术应运而生。这东西只要是用来侦测浏览器工厂自作聪明添加的一些特征,不用说,首当其冲是IE,如自动为table添加tbody,自动为innerHTML去除空白,自动为href属性补全路径……虽然有的的确很有用,如为table添加tbody能加快读写速度,但标准浏览器不这样做,于是麻烦又来了……
innerHTML去除空白特性。按理讲,innerHTML是IE搞出来的,其他浏览器应该完全按照IE的模式渲染才对不起,但它们总要搞出一点特殊来。不过,IE的innerHTML的确有不妥的地方。按微软的思路,innerHTML是用来大规模生成DOM元素,如果有一些空白不是包围在标签之内,将会被忽略掉。这是很细心的处理。但标准浏览器则认为innerHTML生成的是页面的一部分,空白也是,因此空白不会被忽略的。注意运行框的结果,1代表元素节点,3是文本节点,空白也是文本节点的一种。这种特征,jQuery称之为leadingWhitespace。
table自动插入tbody。在表格布局的年代,这特征非常受用的。因为如果没有tbody,table会在浏览器解析到闭合标签时才显示出来,如果起始标签与闭合标签相隔很完,换言之,这表格很大很长,用户会看什么也看不到。但有了tbody分段识别和显示,避免了页面长时间一片空白然后突然一下子内容全部出来的局面。不过,这只因为IE渲染速度太慢的缘故,看看人家的opera与chrome……此特征,jQuery就叫tbody,囧!
object的子元素不可见特性。也就是说,虽然成功渲染了,但我们无法获取里面的这些东西,真是撞鬼了。如果做flash,要临时改动一下参数……此特征,jQuery称之为objectAll。
innerHTML序列化html字符串特性。通常我们用innerHTML把一个符合html标签格子的字符串转换为DOM元素,此过程jQuery称之为序列化,但这序列化在IE中是不完整的,不能序列化为link元素。因此不要用innerHTML动态加载CSS文件。此特征在jQuery的名字叫htmlSerialize。
最新发现(2009,12,11),IE也并不是不支持link元素的序列化,而是存在一些bug。见下面测试
getAttribute对style支持特性。IE会获得一个对象,其他则获得一个字符串……至于setAttribue的情况可见我另一篇博文。此特征在jQuery称之为style,真是莫名其妙的命名啊!
自动补全url特性。IE会把img的src,a的href,form的action全部补全为绝对路径,此bug可以用getAttribute的第二个参数搞定。此特征在jQuery称之为hrefNormalized。
动态解析脚本特性。在标准浏览器中,如果为script添加文本节点,它会把里面的内容解析为脚本,IE则不行,要依赖其text属性,详见我另一篇博文《javascript 动态解析脚本》。此特性,jQuery称之为scriptEval。
克隆事件特性,指用cloneNode方法复制节点时,会连它上面的事件也复制了。jQuery称之为noCloneEvent。
盒子模型特性,IE在不同的渲染模式下,盒子模型是不同的。标准的盒子模型,元素的总宽度等于=左边界+左边框+左补白+宽+右补白+右边框+右边界。怪异模式下,元素的总宽度=左边界+宽+右边界。换言之,怪异模式下,其宽会少一点。我们可以用offsetWidth来验证,offsetWidth的定义可由下图解释得一清二楚!jQuery称之为boxModel。
其他两种cssStyle与opacity就不详说了,IE下都有代替品。在Prototype还检测浏览器对XPath,SelectorsAPI,Element,Element.prototype的支持,innerHTML在select、col、colgroup、frameset、html、title、style、table、tbody、thead、tfoot、tr、td、th中的读写情况。