众所周知,由于 Explorer7 以下的版本对于透明 PNG 的支持非常的不完善。这个问题甚至在一定的程度上,影响了 PNG 格式在 Web 中的使用。

所幸的是,已经有部分的解决方案,那就是「以毒攻毒」使用 Microsoft 的私有滤镜详细 )。

用到 PNG 图片通常有两种方式,分别是图片和背景。在插入 PNG 图片方面,hack 的方法就是使用脚本将原图替换成原图,然后将 img 的 src 属性指向透明的 gif 文件(撑位置)。而在使用 PNG 背景中,就会有些许的问题。

根据官方的文档 ,对于 AlphaImageLoader 的描述如下:

AlphaImageLoader Filter

Displays an image within the boundaries of the object and between 
the object background and content, with options to clip or resize 
the image. When loading a Portable Network Graphics (PNG) image, 
tranparency—from zero to 100 percent—is supported. 

是的,我们 hack 时候加入的图片是处于背景(background)和内容(content)之间的一层。所以滤镜代替使用背景,不能完全实现背景的功能,比如 background-position 以及 background-repeat 等(如有解决的方案,请告知)。

综合上面所述,可以查看 DEMO 。jQuery 方面已经有个名叫 ifixpng 的插件

加入滤镜非常耗费系统资源的,尤其是处理大量图片的情况下。目前已知的情况下,可以使用两种方式载入脚本,第一种就是传统的 Javascript,第二种我也是后来才得知,就是使用 Explorer 的私有属性 behavior CSS 方法( 详细 )。

就个人的观点谈下这两种方法。首先使用传统的 Javascript 方法需要更改结构(加入 script 标签),而 behavior 方法则在 CSS 中指定,并不需要更改结构。同时,behavior 能更好的控制需要渲染的节点(使用 CSS 选择器)。

但 behavior 方法与 CSS expression 一样,需要注意效率问题(由于是 Explorer 属性,效率未知)。并在现有的情况下,CSS 的编写人员可能会对 behavior 方法感到迷惑。

总之,个人认为对于视觉效果方面的 Hack ,能不添加无谓的结构就不添加。正如上面的 behavior 属性可能会造成迷惑一样,在结构中加入某条 script 标签同样会使人迷惑,这是种博弈。

参考资料(部分链接已在文中提及)

-- Split --

后记,在实际测试可能性方案中,发现这两种载入方式的效率不尽相同。在使用 behavior 载入时,页面有明显的载入状态提示,如图

https://friable.rocks/_/2009_11_05/339925d94b8e.jpg

但是用 fidder 追踪发现并没有循环请求数据,如图

https://friable.rocks/_/2009_11_05/531065d94b8d.jpg

虽然出现此现象的原因未知,个人认为 Javascript 载入方式为统一循环渲染,而使用 behavior 时为使用 CSS 选择器获得,它是逐步渲染(了解明确原因的兄弟请告知,谢谢)。

而上述的测试可能有点极端 -- 我添加了 200 个节点。在日常的页面中,使用 behavior 属性情况不大(少于 10 个)、但背景要求质量很高(必须是 PNG,且还有透明)的情况下,还是可以考虑 behavior 属性的。

在 Explorer6 还未完全退出市场之前,加入条 CSS 语句就能解决透明 PNG 的问题(再加上针对 Explorer6 的 hack,其他版本的 Explorer 不受影响),也甚为方便。