视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
IE对CSS样式表的和解决方案
2020-11-27 18:50:04 责编:小采
文档

HTML文档与CSS的关联常见有4种方式:

  1. 使用link标记

    <link rel="stylesheet" type="text/css" href="sheet.css" />
  2. 使用style元素

    <style type="text/css">
    body{background:#fff;}
    h1{font-size:2em;}
    </style>
  3. 使用@import指令

    <style type="text/css">
    @import url(sheet1.css);
    @import "sheet2.css";
    </style>
  4. 使用style属性的内联样式(inline style)

    <p style="color:#f00;">这是红色的字</p>

在实际应用中,使用style属性的内联样式是不推荐使用的,XHTML1.1已经将其标准为不建议使用,原因很简单这种方式不比font标记强多少,削弱了CSS集中控制整个文档外观的优点。前3种方式利用了link标记和style标记,在IE(包括IE6、IE7和IE8 beta1)中有如下:

  1. 文档中只有前31个link或style标记关联的CSS能够应用。

    从第32个开始,其标记关联的CSS都将失效。IE的官方文档All style tags after the first 30 style tags on an HTML page are not applied in Internet Explorer也提及这个,包括在使用.xsl的.xml文件也有这个。但是似乎写错了数量。请在IE看:

    例1:34个style标记同时应用

    例2:1个style标记和34个link标记同时应用

  2. 一个style标记只有前31次@import指令有效应用。

    从第32个@import指令开始忽略。请看:

    例3:在一个style标记中使用34次@import指令。

  3. 一个css文件只有前31次@import指令有效应用。

    从第31个@import指令开始忽略。请看:

    例4:用link标记引入一个使用34次@import指令的css文件

    例5:用style标记引入一个使用34次@import指令的css文件

    例6:用link和style标记分别引入一个使用31次@import指令以上的css文件

  4. 一个CSS文件的不能超过288kb?

    这个消息来自Internet Explorer CSS File Size Limit。

  5. @import指令下层叠不能超过4层

    在IE下通过@import指令引入css文件时,第5层会失效。这个来自Cascade limit via @import rule。实际上,由于浏览器对多层嵌套的支持不完善,所以即使不得已使用了@import指令引入CSS文件,也不要超过2层。

IE对CSS的在绝大部分情况下是不会遇到的,即使遇到最佳的解决方案也应该是手动或者通过后端程序对CSS文件和响应的标记进行合并,最小化的http请求数是优化页面呈现的第一原则。

在IE中,可以通过document.styleSheets对象(Firefox、Opera9和Safari3.1都支持)修改内联和嵌入样式的值。该对象仅在文档包含style或link元素时可用,其实用document.styleSheets.length就可以看出IE下这个值最大是31。下面是利用Javascript来合并linkstyle标记来解决IE下的:

var fnMergeStyleSheet = function(){
if(!document.styleSheets){
 return;
}
var aSheet = document.styleSheets,
 aStyle = document.getElementsByTagName('style'),
 aLink = document.getElementsByTagName('link');
 if(aStyle.length + aLink.length < 32 || !aSheet[0].cssText){ //document.styleSheets.cssText 只有IE支持 
 return;
 }
 var aCssText = [],aCloneLink = []; //把style标签中的样式存入,然后删掉该标签,但保留第一个
 //因为由getElementsByTagName方法返回值是nodeList,所以删除时循环用倒序
 for(var i=aStyle.length-1;i>-1;--i){
 var o = aStyle[i];
 aCssText.push(o.innerHTML);
 if(i>0){
 o.parentNode.removeChild(o);
 }
 } //在IE中只有在31之内的link标签才能通过其styleSheet.cssText获取样式
 //无法的获取复制到一个数组aCloneLink中
 for(var i=aLink.length-1;i>-1;--i){
 var o = aLink[i];
 if(o.getAttribute && o.getAttribute('rel')==='stylesheet'){
 if(o.styleSheet){
 aCssText.push(o.styleSheet.cssText);
 }else{
 aCloneLink.push(o.cloneNode(true));
 }
 if(i>0){
 o.parentNode.removeChild(o);
 }
 }
 }
 var oHead = document.getElementsByTagName('head')[0]; //通过前面的删除,前31个link或者style标记最多只剩下2个
 //通过重新增加link节点的方法激活其styleSheet属性,从而获取样式
 for(var i = aCloneLink.length-1;i>-1;--i){
 var o = aCloneLink[i];
 oHead.appendChild(o);
 aCssText.push(o.styleSheet.cssText);
 oHead.removeChild(o);
 } //把所有的样式都复制给第一个标签
 aSheet[0].cssText += aCssText.join('');
}

上面仅仅是一个简单的粗糙的解决方案,演示请看例1和例2,可以改进的地方还有:

  1. 没有考虑media这个属性,如果有多个media应该分别合并,当然更没有考虑link标记的rel="alternate stylesheet"带来的影响。但我更建议通过@media指令把相应的样式写在同一个文件中,至少可以减少HTTP连接数。

  2. 没有解决@import指令31次的问题,其实可以提取其href值然后进行激活处理。但是实际应用在建议用link标记来替代@import指令,因为在IE中@import指令相当与把link标记写在文档的底部,会导致在IE5/6页面加载时瞬间无样式问题,学名叫“Flash of Unstyled Content”(简称为FOUC)的bug,当然可以通过在文档头中放一个link或script元素可以避免这个bug。

  3. 一般来讲页面之所有出现大量的link或者style标签很可能有很多是相同的,可以在aCssText合并前除掉相同的项,减少代码量。

如果不用DOM中已存在的样式元素直接通过cssText属性添加样式代码,而是创建一个新的样式元素来添加,一定要注意先把新建的样式元素先添加到DOM中,然后再通过cssText属性添加样式代码。反之,其添加的样式代码似乎先被IE6的样式解析器解析后才添加,这样!imporant和hack都将失效。请看例7。不建议通过添加新的样式元素的方式来添加新的样式,这样很容易达到IE的条件。

下载本文
显示全文
专题