早年的东东,贴出来充一下数吧~
问题描述
在一个弹层优化需求中,完成了修改后,刷一下其他(除IE6外)浏览器,很给力,展现都一个样:
再刷下IE6,傻眼了:
初步分析
IE6问题多我知道,不过像这样的问题还是第一次见,它不是某一处的展现问题,而是整个弹层内容……等等,整块内容有问题,某个样式没有加载到?抱着这样的猜测,google了一下,看到下面这句话:
此页面引用的样式文件有三个,一个全局样式(global_min.css),一个弹层样式(css_box_new.css),一个弹层内容样式(css_app.css,以下简称内容样式)。从页面的展现来看,没有引用到的应该是内容样式。检查了一下,果然,页面中设置的charset=utf-8,页面文件也是utf-8编码的,而内容样式是ANSI编码的:
解决方法
此页面是xx站点下的,xx下文件统一用gb2312编码,故将页面的charset值改为gb2312,并将页面文件转为ANSI编码:
修改后再刷下IE6,OK,木有问题了。
进一步探讨
问题虽然解决了,但逻辑上还是说不通:
如果全局和弹层样式与内容样式一样是ANSI编码,为什么一开始它们可以被读取呢?
如果全局和弹层样式不是ANSI编码,那么页面编码修改为ANSI编码后,它们和页面的就不一致了,为什么没有问题呢?
认真思考了三秒钟,无果,去请教了下bboy90,沿着他给出的思路做了下测试:
说明:
样式charset的设置有两种方式,以gb2312为例:
方式一:在css文件的开头设置:
方式二:在<link>中设置:
表格中的“gb2312(样)”指以方式一设置charset为gb2312,“gb2312(link)”指以方式二设置charset为gb2312。
从测试结果可以看出:
- 页面charset、页面编码、样式charset、样式编码全部一致时正常(数据行2、4)——这条结论有点废话,不过还是觉着要验证下;
- 样式charset没有设置时,默认与页面charset一致(数据行1与2、3与4的比较);
- 样式charset可以与页面charset不一致,但一定要与样式编码一致(数据行5、8、7、10)——这说明网上搜到的那句话并不正确,虽然它歪打正着地把问题解决了;
- 以方式一设置样式charset时有效,以方式二设置时无效(数据行5与6、8与9的比较)。
OK,现在我们对编码的一致性原则有了一定的了解,再回过头来分析上面的问题:
经查实,全局和弹层样式都是引用主站的,均为utf-8编码,并且样式文件中没有设置charset,即修改前:
修改后:
为什么内容样式的charset与编码不一致时,会出现问题,而全局和弹层样式的charset与编码不一致时就正常呢?文品问题吗?
根据bboy90的说法,当样式charset与编码不一致时,若注释符号/* */与中文内容间没有空格(如下),则容易出现问题。
检查了一下,果然,全局和弹层样式的注释符号/* */与注释内容间均有空格,而内容样式的注释符号/* */与注释内容间多处没有空格。
为了进一步验证,针对内容样式的几条注释进行了测试:
以上测试并不能得出什么像样的结论,革命尚未成功,同志仍需努力:
大家平时可能也有遇到过,当样式的编码为ANSI时(注意,这里说的是编码为ANSI时,并非样式charset与编码不一致时),编辑注释间的中文时,有时会出现乱码,如:
当我删除“点”时,会变成这样:
继续往左删两次,更奇葩:
……
结合这个和前面的测试,我做了一个大胆的猜想:
当样式charset与编码不一致时,样式文件中中文的解析会出现问题,而中文解析的错误会影响到紧跟在后面的*/,导致*/的解析也出错,*/不被识别到,结果下面的样式就以被注释掉处理了。而添加空格等于在中文和*/间添加一缓冲地带,中文解析错误时影响紧跟其后的空格,空格后面的*/就可以幸免于难了。因中文是两个字节的,添加两个空格应该足以缓冲了。
因多数浏览器的容错机制比较好,所以没有问题,而IE6这个可怜娃儿先天不足、后天畸形,面对这种问题就束手无策了。
但是……
这样的猜测还有点说不通,编辑时乱码是发生在样式编码为ANSI时,与样式charset和编码的一致性无关;而展现异常发生在样式charset和编码不一致性时,与编码是否为ANSI无关。
哦……忙活了半天,还是无果(泪奔)
结论
- 请为样式文件设置charset,并保持与编码一致——考虑到未来的趋势,建议charset和编码均设为utf-8。
- 为了更好地容错,建议注释符号/* */与注释内容间均空两个空格。
2012.12.3