当前位置: 首页 > 图文教程 > 网页制作 > CSS样式表 > CSS 新的图像替换方法

CSS样式表
CSS网页设计 IE8和IE7共存
CSS2 打印属性让打印HTML文档不出问题
制作网页中设计段落缩进的方法
CSS border 属性使用说明
CSS border-style 属性使用方法
CSS border-color 属性使用方法
CSS border-width 属性使用教程
CSS padding属性定义边内补白
CSS margin 属性定义边外补白
网页布局教程 掌握CSS网页布局属性
css 背景样式属性说明
span margin 设置生效
html 滚动条在IE6和IE7中兼容性问题
IE6 两个div有间隙的问题(IE 3px bug)
CSS 数字和字母将容器撑大问题解决
换个角度看页面重构中的语义化
DIY属于个人开发使用的CSS Reset
CSS 空格引起网页布局间距问题
CSS 网页制作时遇到问题的快速参考技巧
css li 去掉点的样式写法

CSS样式表 中的 CSS 新的图像替换方法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-12   浏览: 164 ::
收藏到网摘: n/a

参看 Dave Shea’s excellent summaryPaul Young 在分析现存的所有方法的优缺点之后,提出了一种新的方法,并将其命名为“状态域方法”(The State Method),本文将详细介绍该方法的原理:

现存方法的缺点:

       
  1. 容易失效,例如:图像禁用或者替换图像含有透明区域;
  2.    
  3. 过于复杂不能迅速可靠的执行;
  4.    
  5. 通过js遍历文档树,在页面加载时出现的闪动不尽人意;
  6.    
  7. 可能与一些浏览器不兼容

新的图像替换方法:

新的图像替换技术需要借助于js来实现,但很容易执行,只需要将一小段js引入到头部即可。一旦js执行,响应的规则前将附加“.image-on”,只要客户端的图片未被禁用,规则就会生效,下面是一条应用到h1“状态域方法”的声明:

h1 {
 width: 100px;
 height: 50px;
}

@media screen { 
 .images-on h1 {
   text-indent: -10000px;
   background-image: url(image.png);
   overflow: hidden; 
 }
}

第一条规则总是生效,第二条只有在image未被禁用时生效。“text-indent”使文字偏移于屏幕之外,“overflow:hidden”主要用来在FF下放置锚点在被点击时其焦点偏移于屏幕之外。

第二条规则包绕在@media screen中,主要用来保证图像替换只发生在屏幕阅读器中,而不是在打印状态下执行。如果不这样处理,页面打印时,多数用户将看到一个很大的空隙而不是有意义的文本。

该项技术执行起来很快。因为文本偏移于屏幕之外,图像可以包含透明元素,透过图像本身,你看不到任何文本。Js执行很快,几乎是瞬时的,它充分利用浏览器本身的特性。

方法解析

“状态域方法”是在一种假定的状态下,快速使css规则生效的方法,其上下文背景为document,这样避免了浏览器遍历DOM树。应用“状态域方法”有两个理由:

       
  1. 针对用户的反应,页面部分内容再格式化;
  2.    
  3. 基于客户端浏览器、设备、和其它状况而附加额外的样式。

“状态域方法”通过使用下面的script给html附加一个class。

   document.enableStateScope = function(scope, on)
   {
     var de = document.documentElement;
     if (on)
     de.className += " " + scope;
     else
     de.className = de.className.replace(
       new RegExp("
\\b" + scope + "\\b"), "");
   };

这段js有一点小问题,在示例页中切换功能并不生效,我重新修改了一下,代码如下:

function hasClass(ele,cls) {
return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}
function addClass(ele,cls) {
if (!this.hasClass(ele,cls)) ele.className += " "+cls;
}
function removeClass(ele,cls) {
if (hasClass(ele,cls)) {
var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
ele.className=ele.className.replace(reg,' ');
}
}
document.enableStateScope = function(scope, on) {
var de = document.documentElement;
On ?  addClass(de,scope) : removeClass(de,scope);  
};

上面的hasClass、addClass、removeClass方法借用的是《Pro JavaScript Techniques》提供的方法。如果你使用过jquery,方法将更简单。

“状态域”可以通过下面的方法来切换:

if (condition == true) {
document.enableStateScope("myScope", true);
}

如果“状态域”为“on”,状态域的名字将附加到规则的选择器之前,下面这条规则在条件为真时会将锚点的颜色变成blue。

a { color: red; }
.myScope a { color: blue; }

正如你所预想的那样,状态域图像替代技术是通过检查图像是否被禁用而工作的。如果未被禁用,将激活“image-on”状态域,这很直接了当。


检查图片是否禁用

该方法检查图片是否禁用,并不是请求服务器上的图片,因为那样会导致一次额外的http请求。作者创建了一个巧妙的方法。

在大多数浏览器中,Image对象可以实例化并追溯到一个无效的URL(http://0),这样很容易检测Image的状态。如果禁用,onerror事件将触发,在js文件的开头,j建立一个新的图像对象:

var img = new Image();

但是,有两个古怪的浏览器对此方法并不兼容。在Gecko浏览器中,不论Image是否被禁用。Onerror事件总是被触发。所幸的是,另外一种可行的方案可以解决此问题--给html元素附加一个无效的背景图片,然后通过getComputedStyle方法获得style属性。如果Image禁用,其属性为none或url( invalid-url:):

 if (img.style.MozBinding != null)
 {
   img.style.backgroundImage = "url(" + document.location.protocol + "//0)";
   var bg = window.getComputedStyle(img, '').backgroundImage;
   
   if (bg != "none" && bg != "url(invalid-url:)" || document.URL.substr(0, 2) == "fi")
   {
     document.enableStateScope("images-on", true);
   }
 }

另外一个富有挑战性的浏览器是safari,如果请求是一个无效的URL,safari的状态栏将出现错误提示,但页面布局不受任何影响。如果用户的状态栏处于开启状态,报错将一直持续,这很不专业,同样,作者研究了另外一种可行的方案。如果Image来自于1*1的gif图像,且被数据编码。如果Image禁用,其宽度将为0,以下为在safari中测试的情况:

 else
 {
   img.style.cssText = "-webkit-opacity:0";
   if (img.style.webkitOpacity == 0)
   {
     img.onload = function()
     {
       document.enableStateScope("images-on", img.width > 0);
     }
     img.src = 
       "data:image/gif;base64," +
       "R0lGODlhAQABAIAAAP///wAAACH5BAE" +
       "AAAAALAAAAAABAAEAAAICRAEAOw==";
   }
}

最后,对于其它浏览器,在开始初始化Image对象时,仅仅需要测试onerror触发事件。

   else
   {
     img.onerror = function(e)
     {
       document.enableStateScope("images-on", true);
     }
     img.src = "about:blank";
   }

状态域是可以切换的

可以创建一个系统让用户在文本和替代图像之间切换。

查看示例(示例文件由Paul Young提供)

class属性添加到html之上而不是body或其它子元素之上,主要原因在于在图像替换之前,body需要全面加载。如果“image-on”不添加到html之上。当状态域启用时,将会出现闪动。

图像替换技术是css中相当重要的一部分。鉴于现存图像替换技术的缺点,作者花大量时间另辟蹊径,方法独到,值得借鉴。

示例下载tate-scope-image-replacement.zip

翻译原文:http://www.denisdeng.com/?p=235

英文原文http://www.sitepoint.com/article/image-replacement-state-scope/