快捷搜索:

新的图像替换技术:状态区域法(The State Scope

谢谢蓝色抱负的dishuipiaoxiang的译文,让我懂得到这种崭新的图片调换措施。留意,是图片调换而是图片轮换。信托每一个WEB设计师都要常常用到它!当我们要用到一些特其余字体做LOGO,牌号与Banner时,为了办理用户机不存在这种字体时就只有用图片替代或者应用sIFR规划(@face与eot字体都不靠谱),当然前者是比后者常用得多,也简单得多。而图片调换大年夜法分很多种,如直接暗藏翰墨法,margin移位法,文本缩进法,容器零高度零宽度法……等等。下面,是我根据原译者的文章结合我的理解,从新讲述若何应用此措施。

新的措施,这种被原作者Paul Young称之为The State Scope Method的图片调换技巧,思路异常独特,是把全部文档当成一个状态机,经由过程监视它的状态来绑定或删除它上面的某个类,而这个类携带着显示某个区域的背景图片的信息。换言之,这个类是后期添加上去的,但相对一样平常的JS动态添加,它却又早得多了,由于它是绑定在最顶层的元素html上的!可能在这里,许多人都被搞晕,包括原译者,以是他给出的示例才运行不了。这涉及对照深层次的编程理念,原作者对此也大年夜论了一番设计模式……不过不要紧,我们可以细细阐发。

h1 {

width: 100px;

height: 50px;

}

@media screen {

.images-on h1 {

text-indent: -10000px;

background-image: url(image.png);

overflow: hidden;

}

}

第一条CSS规则老是履行的,h1便是我们所说的要添加背景图片的区域。(原译者翻译The State Scope Method为“状态域法”,虽然看起来对照有味,但不知所云,为了见名达义,我译作“状态区域法”,状态是指html元素的状态,区域是指添加背景图片的区域,这样称呼是不是易懂些呢!)

第二条是选择履行,它看起来有点繁杂,全部困绕在@media screen块中,它是用来包管图像调换只发生在屏幕涉猎器中,而不是在打印状态下履行。假如不这样处置惩罚,页面打印时,多半用户将看到一个很大年夜的闲暇而不是故意义的文本。不过假如我们不打印,它就可有可无了,原作者Paul Young给出的示范页就没有@media screen块了。抛开@media screen不谈,我们发明里面是个后代选择器(Descendant selectors),亦有人称之为包孕选择符,于是这些背景显示信息是否履行处置惩罚,就关键在于它(h1)的先人(.images-on)是否存在了!我们可以经由过程addClass与removeClass为html动态添加或删除.images-on类。

下面是核心代码:

var hasClass = function(ele,cls) {

return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));

}

var addClass = function(ele,cls) {

if (!this.hasClass(ele,cls)) ele.className += " "+cls;

}

var removeClass = function(ele,cls) {

if (hasClass(ele,cls)) {

var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');

ele.className=ele.className.replace(reg,' ');

}

}

/**

*@scope是某个区域中设置若何实现图片调换的类,是要绑定于html元素上

*@on为html元素的状态,用于动态绑定或删除上面的scope类

*/

document.enableStateScope = function(scope, on) {

var de = document.documentElement;

on ?addClass(de,scope) : removeClass(de,scope);

};

那么剩下的问题便是若何监视html元素的状态或鉴定html元素的状态。这个实现着实很奇妙,它经由过程检测Image工具是在发生onerror变糊弄为on赋true值或false值(根据javascript的事故传播机制,子元素的大年夜多半初级事故会冒泡到上一级元素直至最顶层元素,假如该元素也有处置惩罚此事故的能力就履行此事故)。很显着,onerror是个很原始的事故,一处发生差错,全部文档就会报错。根据我们上面的提法,Image工具 onerror的状态便是html元素的状态,并且判断html元素的状态,远比经由过程遍历DOM树后才能定位到背景图片所在的元素,再进行鉴定要快!

既然是检测Image工具,那么我们首先要知道此元素是否存在,但我们不是检测它是否存在于办事器端,那会导致一次额外的http哀求。作者创建了一个奇妙的措施。

在大年夜多半浏览器中,Image工具可以实例化并会自动追加一个无效的URL(http://0),经由过程它我们就很轻易判断这图片是否可用。由于假如是这样,就会触发onerror事故,那么我们就把on设置为false,否则为true。这此,我们可以在JS中,动态创建一个Image工具。

var img = new Image();

然则,有两个游览器对此措施并不兼容。在Gecko内审浏览器中(如FF),不论Image是否可用,老是会引发onerror事故,是以我们原本的鉴定规划就行不通了。幸好,我们找到另一个措施。我们可能为html元素添加一个无效的背景图片,然后经由过程getComputedStyle措施得到其 style.backgroundImage值,假如图片弗成用,则此值为 none或者url(invalid-url:)。这时,我们就可以宁神给on设置为false了!

if (img.style.MozBinding != null){ /*判断是否为火狐*/

/*强制设置图片的Url为http://0 */

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"){

/**

*假如图片的Url值不为 none与url(invalid-url:),或者地址栏不为file:///

*那么设置on为true

*/

document.enableStateScope("images-on", true);

}

}

别的一个富有寻衅性的浏览器是safari,假如哀求是一个无效的URL,safari的状态栏将呈现差错提示,但页面结构不受任何影响。假如用户的状态栏处于开启状态,报错将不停持续,这很不专业,为此,作者提出了别的一种可行的规划。经由过程base64编码动态天生一个1*1的gif图片,来阻拦不停报错。假如图片弗成用,它的宽度将为零,我们可能用它作为我们鉴定的标准。

if (img.style.MozBinding != null) { /*判断是否为火狐*/

/奸淫奸淫奸淫奸淫略奸淫奸淫奸淫奸淫/

}else {

img.style.cssText = "-webkit-opacity:0";

if (img.style.webkitOpacity == 0) { /*判断是否为safari*/

img.onload = function(){

/*假如图片的宽大年夜于零,证实图片可用,我们把on设置为true,否则为false*/

document.enableStateScope("images-on", img.width > 0);

}

/*动态天生gif图片,预防由于图片不存在,不停报错!*/

img.src ="data:image/gif;base64,"

+"R0lGODlhAQABAIAAAP///wAAACH5BAE"

+"AAAAALAAAAAABAAEAAAICRAEAOw==";

}

}

着末,对付其它浏览器,在开始初始化Image工具时,仅需检测onerror事故是否发生。

if (img.style.MozBinding != null) {

/奸淫奸淫奸淫奸淫略奸淫奸淫奸淫奸淫/

}else {

if (img.style.webkitOpacity == 0){

/奸淫奸淫奸淫奸淫略奸淫奸淫奸淫奸淫/

}else{

img.onerror = function(e) {

document.enableStateScope("images-on", true);

}

/*取消onerror事故*/

img.src = "about:blank";

}

}

下面给出完备措施,使用闭包维持enableStateScope措施不停存鄙人去!

(function(){

d=document;e=d.documentElement;c="images-on";i=new Image();t=i.style;s=d.enableStateScope=function(s,o){

if(o)e.className+=" "+s;else e.className=e.className.replace(new RegExp("\\b"+s+"\\b"),"");

};if(t.MozBinding!=null){

t.backgroundImage="url("+d.location.protocol+"//0)";b=window.getComputedStyle(i,'').backgroundImage;if(b!="none"&&b!="url(invalid-url:)"||d.URL.substr(0,2)=="fi")s(c,true);

}else{

t.cssText="-webkit-opacity:0";if(t.webkitOpacity==0){

i.onload=function(){

s(c,i.width>0);

};i.src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";

}else{

i.onerror=function(){

s(c,true);

};i.src="about:blank";

}

}

})();

The State

Scope

id="stateScopeOff">现在images-on这个类

是不存在的。是否添加它?

id="stateScopeOn">现在images-on这个类

已经存在。是否删掉落它?

运行代码

http://www.denisdeng.com/exzample/state-scope-image-replacement.html

此措施的一些优点

当客户真个电脑不支持javascript与禁止图片显示时,它都能优雅地降级而不致于页面效果有太多的差异

支持半透明或透明的图片

实现异常简单,只要导入我们的脚本以及设置必要图片调换的区域

因为是用异常根基的技巧,纵然是过气的游览器中也通顺无阻

相符标准,对屏幕涉猎器与搜索引擎友好

不必要添加额外的标签

不耗损内存(由于基础不遍历DOM树)

纵然是页面加载完毕对DOM进行操作也不会影响它的效果

在加载历程基础不会激发或只有稍微的闪烁征象

文本与图片可以在容器元素设置居中或居左对齐

不要求在办事器端存在一张1*1的gif图片来防止掉足

在显示器与打印页上都显示优越

因为是应用CSS background-image属性来设置图片,便于我们应用image sprites技巧来削减哀求数

附上原作者Paul Young的文章:

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

您可能还会对下面的文章感兴趣: