瀏覽器中css實現html元素透明)

來源:互聯網
上載者:User

  今天看到一位前端開發技術達人(秦歌 & Kaven)的文章《CSS實現HTML元素透明的那些事》,關於瀏覽器中透明的實現。摘載如下:

 

  CSS3草案中定義了{opacity: | inherit;}來聲明元素的透明度,這已經得到了大多數現代瀏覽器的支援,而IE則很早通過特定的私人屬性filter來實現的,所以HTML元素的透明效果已經無處不在了。首先看看A級瀏覽器所支援的用CSS實現元素透明的方案:

 

瀏覽器 最低
版本
方案
Internet Explorer 4.0 filter: alpha(opacity=xx);
5.5 filter: progid:DXImageTransform.Microsoft.Alpha(opacity=xx);
8.0 filter: "alpha(opacity=xx)";
filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=xx)";
-ms-filter: "alpha(opacity=xx)";
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=30)";
Firefox (Gecko) 0.9 (1.7) opacity
Opera 9.0 opacity
Safari (WebKit) 1.2 (125) opacity

 

  實際上在IE8中,-ms-filter是filter的別名,兩者區別是-ms-filter的屬相值必須被單引號或雙引號包圍,而filter中則不是必須,而在IE8之前的版本中,filter的屬性值必須不被單引號或雙引號包圍。

  IE中的HTML元素要實現透明,則其必須具備layout,這樣的元素有僅可讀的屬性hasLayout,且其值為true。具體情況如下:

  1. bodyimgtabletrthtd等元素的hasLayout一直為true
  2. typetextbuttonfileselectinputhasLayout一直為true
  3. 設定{position:absolute}的元素的hasLayouttrue
  4. 設定{float:left|right}的元素的hasLayouttrue
  5. 設定{display:inline-block}的元素的hasLayouttrue
  6. 設定{height:xx}{width:xx}的元素必須具體以下兩個條件之一,其hasLayout才能為true
    1. IE8相容模式和IE8以前的瀏覽器中,在標準(strict)模式下其display的值是block,如demo3就不行。
    2. 元素在怪癖模式(compat mode)下。
  7. 設定了{zoom:xx}的元素在IE8的相容模式或IE8之前的瀏覽器中其hasLayouttrue,但在IE8的標準模式下則不會觸發hasLayout
  8. 設定了{writing-mode:tb-rl}的元素的hasLayouttrue
  9. 元素的contentEditable的屬性值為true
  10. 在IE8標準模式下設定了{display:block}的元素的hasLayout一直為true,如demo8。

  關於hasLayout的更多詳情可以看Exploring Internet Explorer “HasLayout” Overview和On having layout

從上面就可以看出IE實現HTML元素的透明如此混亂,為了向下相容和自己的私人屬性讓IE上實現元素透明有多種方式,比如CSS Opacity執行個體中的demo1到demo8,雖然IE團隊推薦實現透明的方式是:

 

{  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);  opacity: .5;}

 

而目前簡單最好用的實現方式是如CSS Opacity中demo4這樣:

 

{    filter:alpha(opacity=30);    opacity:.3;}
 

  實際上目前最流行的JavaScript架構的設定樣式方法都是應用這種方式,並且針對IE設定了{zoom:1}來讓元素的hasLayouttrue,但在IE8的標準模式下zoom並不能觸發hasLayout,所以利用它們設定hasLayoutfalse的元素的透明度時在IE8的標準模式下是失敗的,這個bug在YUI、Prototype、jQuery和Mootools的最新版本中都存在,具體請在IE8標準模式下看demo9到demo11。同樣由於在IE8中設定透明度的方式多種多樣,所以利用JavaScript擷取HTML元素的透明度值需要考慮多種情況,YUI完美解決了這個問題,Prototype比jQuery稍微周全一點,而Mootools直接是bug,具體可以在IE下看demo1到demo8的示範。從這個角度給4個架構來個排名的話,YUI第一、Prototype第二、jQuery第三、Mootools墊底。

 

  我簡單的實現了設定和擷取Opacity的函數,可以避開上面架構存在的bug,請在IE8標準模式下看demo12:

  //設定CSS opacity 屬性的函數,解決IE8的問題
  var setOpacity = function(el,i){
    if(window.getComputedStyle){// for non-IE
      el.style.opacity = i;
    }else if(document.documentElement.currentStyle){ // for IE
      if(!el.currentStyle.hasLayout){
        el.style.zoom = 1;
      }
      if(!el.currentStyle.hasLayout){ //在IE8中zoom不生效,所以再次設定inline-block
        el.style.display = 'inline-block';
      }
      try{
        //測試是否已有filter
        //http://msdn.microsoft.com/en-us/library/ms532847%28VS.85%29.aspx
        if(el.filters){
          if(el.filters('alpha')){
     el.filters('alpha').opacity = i * 100;
   }else{
     el.style.filter += 'alpha(opacity='+ i * 100 +')';
    }
         }
      }catch(e){
        el.style.filter = 'alpha(opacity='+ i * 100 +')';
      }
    }
  }

 

  //擷取CSS opacity 屬性值的函數
  //借鑒自http://developer.yahoel.com/yui/docs/YAHOO.util.Dom.html#method_getStyle
  var getOpacity = function(el){
    var value;
    if(window.getComputedStyle){
      value = el.style.opacity;
      if(!value){
        value = el.ownerDocument.defaultView.getComputedStyle(el,null)['opacity'];
      }
      return value;
    }else if(document.documentElement.currentStyle){
      value = 100;
      try { // will error if no DXImageTransform
          value = el.filters['DXImageTransform.Microsoft.Alpha'].opacity;
      } catch(e) {
          try { // make sure its in the document
              value = el.filters('alpha').opacity;
          } catch(err) {
          }
      }
      return value / 100;
    }
  }

 

 

  在沒有看到秦哥這篇文章前,我的瞭解是:

  function setOpacity(obj, opacity) {
    opacity = (opacity =100)?99.999:opacity;
    if (obj<0) obj=0; else if (obj>100) obj = 100;

    // IE/Win
    obj.style.filter = "alpha(opacity:"+opacity+")";
    // Safari<1.2, Konqueror
    obj.style.KHTMLOpacity = opacity/100;
    // Older Mozilla and Firefox
    obj.style.MozOpacity = opacity/100;
    // Safari 1.2, newer Firefox and Mozilla, CSS3
    obj.style.opacity = opacity/100;
   }

  運行這個函數的效果可想而知.....

 

  在《Pro JavaScript Techniques》中的是:

  //設定透明度    
  function setOpacity(elem,num){
       if(elem.filters){
           elem.style.filter="alpha(opacity="+num+")";
           }else{
               elem.style.opacity=num/100;
               }
       }

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.