DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> CSS入門知識 >> CSS詳解 >> 新的圖像替換方法
新的圖像替換方法
編輯:CSS詳解     

熟悉CSS的開發者一定知道圖像替換技術,也深知它的意義,Dave Shea 曾在他的一篇文章對此做了詳細的總結,參看 Dave Shea’s Excellent summary ,Paul Young 在分析現存的所有方法的優缺點之後,提出了一種新的方法,並將其命名為“狀態域方法”(The State Method),本文將詳細介紹該方法的原理:

現存方法的缺點:

  1. 容易失效,例如:圖像禁用或者替換圖像含有透明區域;
  2. 過於復雜不能迅速可靠的執行;
  3. 通過JS遍歷文檔樹,在頁面加載時出現的閃動不盡人意;
  4. 可能與一些浏覽器不兼容

新的圖像替換方法:

新的圖像替換技術需要借助於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. 基於客戶端浏覽器、設備、和其它狀況而附加額外的樣式。

“狀態域方法”通過使用下面的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中相當重要的一部分。鑒於現存圖像替換技術的缺點,作者花大量時間另辟蹊徑,方法獨到,值得借鑒。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved