最近遇到了两个IE下的兼容问题(产品目前还需要兼容IE8,所以没办法,运行效果虽然不好,但是也仍然兼容着吧)
问题描述:
1, 在更改IE窗口的时候,反应非常慢,甚至卡死
2, 在chrome运行正常,但是在IE8下样式大片失效
分析原因:
问题1: 通过查找, 发现是IE下对 window 的 resize 事件的判断并不是以windows 为准, 而是任何 dom 元素的更改都会触发此事件.
由于项目是基于 reactjs 的组件, 并且会监听 resize 事件从而做出自适应调整. 此调整又会导致 IE 下的 resize 事件, 从而, 死循环 诞生.
问题2: 感觉不是兼容问题导致的, 因为很多的样式失效. 组内一哥们经过"深入"钻研, 发现更改总 less 文件的 import 会部分解决此问题,
但仍然会导致其他模块的样式更改. 我一起参与分析后, 发现样式在IE下就像丢失一样, 不仅仅是兼容问题. 经过查找, 发现在IE9下的css rule
有长度限制(单个文件, 即单个CSS 文件限制rule数量为 4096. 此处做一个自己的说明, 此处的 rule , 即为一条 css 规则, 如果有逗号的多个
写在一行的规则, 是会计算为多个规则的~~~~) 所以单纯的抽离出来CSS样式, 写为一行是不可以的. 虽然代码量减少, 但是rule 数量并没有
减少多少. 需要对样式进行公共性归纳, 处理, 调整CSS的规则.
问题解决:
1: 通过在 resize 事件的时候 增加判断窗口大小是否更改进行解决
示例方法如下:
//so的搬运工 ^_^
var winWidth = $(window).width(),
winHeight = $(window).height(); $(window).resize(function(){
var onResize = function(){
//The method which alter some css properties triggers
//window.resize again and it ends in an infinite loop
someMethod();
} //New height and width
var winNewWidth = $(window).width(),
winNewHeight = $(window).height(); // compare the new height and width with old one
if(winWidth!=winNewWidth || winHeight!=winNewHeight){
window.clearTimeout(resizeTimeout);
resizeTimeout = window.setTimeout(onResize, 10);
}
//Update the width and height
winWidth = winNewWidth;
winHeight = winNewHeight;
});
2: 通过精简css rule进行处理. 判断有多少rule的js(在非IE下运行~~)
function countCSSRules() {
var results = '',
log = '';
if (!document.styleSheets) {
return;
}
for (var i = 0; i < document.styleSheets.length; i++) {
countSheet(document.styleSheets[i]);
}
function countSheet(sheet) {
if (sheet && sheet.cssRules) {
var count = countSelectors(sheet); log += '\nFile: ' + (sheet.href ? sheet.href : 'inline <style> tag');
log += '\nRules: ' + sheet.cssRules.length;
log += '\nSelectors: ' + count;
log += '\n--------------------------';
if (count >= 4096) {
results += '\n********************************\nWARNING:\n There are ' + count + ' CSS rules in the stylesheet ' + sheet.href + ' - IE will ignore the last ' + (count - 4096) + ' rules!\n';
}
}
}
function countSelectors(group) {
var count = 0
for (var j = 0, l = group.cssRules.length; j < l; j++) {
var rule = group.cssRules[j];
if (rule instanceof CSSImportRule) {
countSheet(rule.styleSheet);
}
if (rule instanceof CSSMediaRule) {
count += countSelectors(rule);
}
if( !rule.selectorText ) {
continue;
}
count += rule.selectorText.split(',').length;
}
return count;
} console.log(log);
console.log(results);
};
countCSSRules();
OK, 完毕. 附上自己参考的地址. 对于前端来说 * 的确是好地方, 要经常去查找看看. 这是一个认真做事的地方.
http://*.com/questions/1852751/window-resize-event-firing-in-internet-explorer
http://*.com/questions/9906794/internet-explorers-css-rules-limits