熟悉css的開發者一定知道圖像替換技術,也深知它的意義,Dave Shea 曾在他的一篇文章對此做了詳細的總結,參考Dave Shea's excellent summary , Paul Young在分析現存的所有方法的優缺點之後,提出了一種新的方法,並將其命名為「狀態域方法」(The State Method),本文將詳細介紹該方法的原理:
現存方法的缺點:
新的圖像替換方法:
新的影像替換技術需要藉助於js來實現,但很容易執行,只需要將一小段js引入頭部即可。一旦js執行,回應的規則前將附加“.image-on”,只要客戶端的圖片未被停用,規則就會生效,下面是一條應用到h1“狀態域方法”的聲明:
第一條規則總是生效,第二條只有在image未被停用時生效。 「text-indent」使文字偏移於螢幕之外,「overflow:hidden」主要用來在FF下放置錨點在被點擊時其焦點偏移於螢幕之外。
第二條規則包繞在@media screen中,主要用來確保影像替換只發生在螢幕閱讀器中,而不是在列印狀態下執行。如果不這樣處理,頁面列印時,多數用戶將看到一個很大的空隙而不是有意義的文字。
該項技術執行起來很快。因為文字偏移於螢幕之外,圖像可以包含透明元素,透過圖像本身,你看不到任何文字。 Js執行很快,幾乎是瞬時的,它充分利用瀏覽器本身的特性。
方法解析
「狀態域方法」是在一種假定的狀態下,快速使css規則生效的方法,其上下文背景為document,這樣避免了瀏覽器遍歷DOM樹。應用「狀態域方法」有兩個理由:
「狀態域方法」透過使用下面的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」狀態域,這很直接了當。
h1 {
width: 100px;
height: 50px;
}
@media screen {
.images-on h1 {
text-indent: -10000px;
background-image: url(image.png);
overflow: hidden;
}
}