一些关于IE6的兼容问题总结,希望能帮到那些那些有需要的人。。。
Hack篇
条件Hack
<!--[if <keywords>? IE <version>?]>
HTML代码块
<![endif]-->
<keywords>
if条件共包含6种选择方式:是否、大于、大于或等于、小于、小于或等于、非指定版本
- 是否:指定是否IE或IE某个版本。关键字:空
- 大于:选择大于指定版本的IE版本。关键字:gt(greater than)
- 大于或等于:选择大于或等于指定版本的IE版本。关键字:gte(greater than or equal)
- 小于:选择小于指定版本的IE版本。关键字:lt(less than)
- 小于或等于:选择小于或等于指定版本的IE版本。关键字:lte(less than or equal)
- 非指定版本:选择除指定版本外的所有IE版本。关键字:!
<version>
目前的常用IE版本为6.0及以上,推荐酌情忽略低版本,把精力花在为使用高级浏览器的用户提供更好的体验上
[附参考手册]
属性级 Hack
selector{<hack>?property:value<hack>?;}
property 前缀
- _ :选择IE6及以下。连接线(中划线)(-)亦可使用,为了避免与某些带中划线的属性混淆,所以使用下划线(_)更为合适。
- * :选择IE7及以下。诸如:(+)与(#)之类的均可使用,不过业界对(*)的认知度更高
- \9 :选择IE6+
- \0 :选择IE8+和Opera
value 后缀
- [;property:value;]; :选择webkit核心浏览器(Chrome,Safari)。IE7及以下也能识别。中括号内外的3个分号必须保留,第一个分号前可以是任意规则或任意多个规则`[;color:#f00;];` 与 `[color:#f00;color:#f00;];` 与 `[margin:0;padding:0;color:#f00;];` 是等价的。生效的始终是中括号内的最后一条规则,所以通常选用第一种写法最为简洁。
IE6/7/8 各不相同
.test{
color:#c30; /* For Firefox */
[;color:#ddd;]; /* For webkit(Chrome and Safari) */
color:#090\0; /* For Opera */
color:#00f\9; /* For IE8+ */
*color:#f00; /* For IE7 */
_color:#ff0; /* For IE6 */
}
选择符级Hack
选择符级Hack定义和用法
<hack> selector{ sRules }
* html .test{color:#090;} /* For IE6 and earlier */
* + html .test{color:#ff0;} /* For IE7 */
.test:lang(zh-cn){color:#f00;} /* For IE8+ and not IE */
.test:nth-child(1){color:#0ff;} /* For IE9+ and not IE */
跨域通信篇
JSONP
由于 IE6/7 不支持 CORS,跨域 ajax 用 jsonp 实现,[参考教程]
$.getJSON("https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=?", function(data) {
// do something
});
Iframe
利用 iframe 可跨域请求页面的特点,可将需要的数据单向传递给子页面
// parent domain www.a.com
iframe.src = href + '#' + data
// child domain www.b.com
var data = JSON.parse(location.hash)
IE 6/7 不支持 JSON 对象,需要额外做扩展,如 json2.js
Navigator
IE6/7 有个漏洞,跨域 iframe 和当前网页共享一个 navigator,通过给 navigator 注册一个事件,就可以达到跨域通信的目的。
参考项目 [MessengerJS]
该项目在 IE6/7 下使用 navigator,其它浏览器使用 postMessage 实现跨域通信的兼容,推荐使用。
源码 50 行有误,可参考我修改过的 [MessengerJS]
document.domain
如果页面地址的一级域名相同,可使用 document.domain = '一级域名' 来设置相同的域,以达到跨域。
关于 IE6 不支持透明度
IE6 原生只支持透明,但不支持透明度的设置,图像也是一样。所有半透明像素会根据不同的图片格式有不同的表现。
PNG
同样是一张带有透明的 png 图片,背景色也会不同,以下仅为 IE6 的表现。PNG图片导出方法参见 [Adobe Helpx]
PNG | 8位 | 24位 | 32位 |
---|---|---|---|
背景填充 | 透明 | 白色 | 灰色 |
特点 | 品质较低,锯齿较明显 | 品质较高,不保留透明数据,同 jpg | 品质最高,保留透明数据 |
如何选择?
下情况可以使用 8位 PNG:
- 图片较小,锯齿啥的看不太清
- 细节不多,大都是简单线条加简单光影效果
以下尽量选择用 32位 PNG,用 DD_belatedPNG 这个库添加透明效果(实际是用两个 VML 代替滤镜,占用两个 DOM 节点,参考[官方介绍](http://www.dillerdesign.com/experiment/DD_belatedPNG/#how "官方介绍") ):
- 图片较大,需要作为组件主体的背景之类的
- 细节保留较多,复杂的光影效果
如果需要做背景切换,通过直接修改 style 属性就会触发 DD_belatedPNG 重新渲染
GIF
IE6 是支持透明 GIF 的,包括动图,同 PNG 一样,不支持的仅是透明度。也是 8位的。
动图其实也就是多张 8位的 PNG 插入了 GIF 的容器,然后循环播放。(我是这么理解的。。。)
可以代替动画吗?
可选,IE6 有一个 bug。当用户点击 a 标签时,会触发 beforeUnload 事件,无论 a 标签的 href 属性写的啥(除了 '#'),在这个事件中会停止页面所有 GIF 运行。
a 标签的作用
IE6 只有 a 标签支持伪类(hover,active),为保证良好的交互,此处鼠标悬停、点击状态可以用 css 完成,但会影响 gif 运行;也可以用 js 实现($(ele).hover()),但需要注意背景图片替换的问题。根据项目情况选择。
IE6/7 的垃圾回收机制
目前主流的浏览器垃圾回收使用的是 标记-清除算法(进入环境/可达 的变量添加标记,离开删除标记,定时清除未标记的变量),而 IE6/7 使用的引用计数(引用 +1,用完 -1,函数执行完标记为 0 的将被回收,对象存在被引用,就不会进入 GC),如
function f(){
var o = {};
var o2 = {};
o.a = o2; // o 引用 o2
o2.a = o; // o2 引用 o
return "azerty";
}
f();
如果函数内时 DOM 对象,就会占用很多内存,很容易造成内存溢出,甚至浏览器崩溃。详情参考 [内存管理]
循环引用时需要注意避免闭包内的对象的声明和引用,或者手动清除,如 a = null
IE 对 https 的支持情况
XP 对 https 支持有限,最多对 SSL2.0、SSL3.0、TLS1.0 支持
支付宝官方已使用 TLS1.2,XP系统原生已不再支持,使用时需注意。