阳光男孩 发表于 2009-01-05
图像替换是网站前端设计中经常使用的技巧之一。本文在pFIR图像替换技术的基础上,提出了一个改进版本。
什么是图像替换(FIR)?
考虑这样一种情况:
<h4>Image Replacement</h4>,效果:Image Replacement
现在希望用一张图片替换掉文字内容,使得网页更加丰富多彩(很多情况下是为了表现出特殊字体效果)。做到这种效果:
PerfectWorks大牛的blog介绍了常见的几种FIR技术: 谈谈CSS图像替换技术(FIR)。
PerfectWorks认为,图像替换技术中最难解决的问题是有些用户关闭了图像显示、而浏览器支持CSS——某些FIR解决方案在这种情况下会造成图片不显示、而原来的文字也不见了。
PerfectWorks也提出了他自己的一种图像替换技术:用JavaScript实现完美图像替换(pFIR)
但是,pFIR有几个缺陷:
function pFIR_improved(className,className2) {
ImageSupport(function(){//仅当打开图像显示时执行图像替换
var d=null;
var z=0;//尚未完成预载入的图片数量
var done=false;
var g=function() {
if (--z>0) return;//又载入了一幅图片,全部载入了吗?
if (done) return; done=true;
if (d) document.body.removeChild(d);
var c1=' '+className+' ',c2=' '+className2;
var r=function(E) {
for (var i=0,ilen=E.length;i<ilen;++i) {
var e=E[i];
if ((' '+e.className+' ').indexOf(c1)>=0) {
e.className+=c2;//执行图像替换
}
}
}
var E=document.getElementsByTagName('*');
if (!E || E.length<1) {
var HTML=['A','ABBR','ACRONYM','ADDRESS','APPLET','AREA','B','BASE','BASEFONT','BDO',
'BIG','BLOCKQUOTE','BODY','BR','BUTTON','CAPTION','CENTER','CITE','CODE','COL',
'COLGROUP','DD','DEL','DFN','DIR','DIV','DL','DT','EM','FIELDSET','FONT','FORM',
'FRAME','FRAMESET','H1','H2','H3','H4','H5','H6','HEAD','HR','HTML','I','IFRAME',
'IMG','INPUT','INS','ISINDEX','KBD','LABEL','LEGEND','LI','MAP','MENU','META',
'NOFRAMES','NOSCRIPT','OBJECT','OL','OPTGROUP','OPTION','P','PARAM','PRE','Q','S',
'SAMP','SELECT','SMALL','SPAN','STRIKE','STRONG','SUB','SUP','TABLE','TBODY','TD',
'TEXTAREA','TFOOT','TH','THEAD','TITLE','TR','TT','U','UL',
'VAR'];//HTML 4.01 elements except LINK,SCRIPT,STYLE
for (var i=0,ilen=HTML.length;i<ilen;++i) r(document.getElementsByTagName(HTML[i]));
} else {
r(E);
}
};
try{
d=document.createElement('div');//包含预载入图片的容器
d.style.position='absolute';
d.style.visibility='hidden';
d.style.zIndex='-1';
var P={};
var STYLE=document.styleSheets;
var c2='.'+className2;
for (var i=0,ilen=STYLE.length;i<ilen;++i) {//遍历所有样式表
var style=STYLE[i];
var R=style.cssRules;
if (!R) R=style.rules;
for (var j=0,jlen=R.length;j<jlen;++j) {//遍历所有样式规则
var r=R[j];
var bg=r.style.backgroundImage;
if ((r.selectorText).indexOf(c2)<0 || !bg || bg=='') continue;
//找到selector包含className2、并定义了background-image属性的样式规则
var m=bg.match(/url\(["']?([^\("'\)]+)["']?\)/);//取出background-image属性中的URL地址
if (!m) continue;
var im=m[1];
if (im.substr(0,5)=='data:') continue;
if (P[im]) continue;//已经开始预载入了
P[im]=true;
var img=document.createElement('img');//预载入图片
img.src=m[1];
if (img.width<20) {
img.onload=g;
++z;
}//已缓存时能马上取得width,未缓存时width为0
d.appendChild(img);
}
}
document.body.appendChild(d);
if (z<=0) g();//没有图像需要预载入,直接执行替换
else setTimeout(function(){z=-4;g();},4000);//如果4秒仍未完成预载入,仍然执行图像替换
}catch(ex){
d=null;
g();//出现错误(可能是不支持样式表遍历),直接执行替换
}
}); }
以上代码兼容的浏览器:Firefox3,Firefox2,Opera9,Chrome,IE8,IE7,IE5.5