javascript的可控式透明特效

來源:互聯網
上載者:User

透明特效是script.aculo.us提到的特效中最簡單的特效之一。既然是特效,必須涉及時間與空間的概念。時間我們可以用setTimeout與setInterval,個人比較喜歡setTimeout,雖然它每次調用都重複註冊,但可控性比較好。空間就全憑CSS的絕對位置實現位移了。在開始之前,我們練習一下setTimeout的遞迴用法(用來類比setInterval)。

  function text(el){    var node  = (typeof el == "string")? document.getElementById(el) : el;    var i = 0;    var repeat = function(){      setTimeout(function(){        node.innerHTML = "<h1>"+i+"</h1>";        i++;        if(i <= 100){          setTimeout(arguments.callee, 100);        }      },100)    }    repeat();  }

我們來試一下最簡單的淡入特效,就是把node.innerHTML那一行改成透明度的設定。

  function fadeIn(el){    var node  = (typeof el == "string")? document.getElementById(el) : el;    var i = 0;    var fade = function(){      setTimeout(function(){               !+"\v1"? (node.style.filter="alpha(opacity="+i+")"): (node.style.opacity = i / 100);        i++;        if(i <= 100){          setTimeout(arguments.callee, 100);        }      },100)    }    fade();  }

但是這樣並不完美,因為IE的濾鏡可能會在IE7中失效,我們必須要用zoom=1來啟用hasLayout。我們再添加一些可制定參數擴充它。注釋已經非常詳細,不明白在留言裡再問我吧。

  function opacity(el){    //必選參數    var node  = (typeof el == "string")? document.getElementById(el) : el,    //選擇性參數    options = arguments[1] || {},    //變化的期間    duration = options.duration || 1.0,    //開始時透明度    from = options.from || 0.0 ,    //結束時透明度    to = options.to || 0.5,    operation = 1,    init = 0;    if(to - from < 0){      operation = -1,      init = 1;    }    //內部參數    //setTimeout執行的間隔時間,單位毫秒    var frequency = 100,    //設算重複調用的次數    count = duration * 1000 / frequency,    // 設算每次透明度的遞增量    detal = Math.abs(to - from)  /count,    // 進行中的次數    i = 0;    var main = function(){      setTimeout(function(){        if(!+"\v1"){          if(node.currentStyle.hasLayout)  node.style.zoom = 1;//防止濾鏡失效          node.style.filter="alpha(opacity="+ (init * 100 + operation * detal * i * 100).toFixed(1) +")"        }else{          node.style.opacity =  (init + operation * detal * i).toFixed(3)        }        node.innerHTML =  (init + operation * detal * i).toFixed(3)        i++;        if(i <= count){          setTimeout(arguments.callee, frequency);        }      },frequency)    }    main();  }
<div class="text" onclick="opacity(this,{duration:4.0,from:0.0,to:1})"></div><div class="text" onclick="opacity(this,{duration:4.0,from:1.0,to:0})"></div>

但上面並不盡善盡美,有一個Bug。我們是通過短路運算子來決定是否使用預設參數還是我們傳入的參數,但在javascript中,數字0甚至0.0都會自動轉換為false。因此在第個例子,如果我們在to中傳入0,它永遠不會用到這個0,而是預設的0.5。解決方案讓它變成字串“0”。另,參數i也不是必須的,我們可以省去它,用count負責所有的迴圈,但這樣一來,我們的思維就要逆過來想了。原來是加的,我們要變成減的。

  function opacity(el){    //必選參數    var node  = (typeof el == "string")? document.getElementById(el) : el,    //選擇性參數    options = arguments[1] || {},    //變化的期間    duration = options.duration || 1.0,    //開始時透明度    from = options.from || 0.0 ,    //結束時透明度    to = (options.to && options.to + "") || 0.5,    operation = -1,    init = 1;    if(to - from < 0){      operation = 1,      init = 0;    }    //內部參數    //setTimeout執行的時間,單位    var frequency = 100,    //設算重複調用的次數    count = duration * 1000 / frequency,    // 設算每次透明度的遞增量    detal = operation * Math.abs(to - from) /count;    var main = function(){      setTimeout(function(){        if(!+"\v1"){          if(node.currentStyle.hasLayout)  node.style.zoom = 1;//防止濾鏡失效          node.style.filter="alpha(opacity="+ (init * 100 +  detal * count * 100).toFixed(1) +")"        }else{          node.style.opacity =  (init +  detal * count).toFixed(3)        }        count--;        if(count + 1){          setTimeout(arguments.callee, frequency);        }      },frequency)    }    main();  }

進一步最佳化,利用原型共用方法。

  function Opacity(el){    var node  = (typeof el == "string")? document.getElementById(el) : el,    options = arguments[1] || {},    duration = options.duration || 1.0,    from = options.from || 0.0 ,    to = (options.to && options.to + "") || 0.5,    operation = -1,    init = 1;    if(to - from < 0){      operation = 1,      init = 0;    }    var frequency = 100,    count = duration * 1000 / frequency,    detal = operation * Math.abs(to - from) /count;    this.main(node,init,detal,count,frequency);  }  Opacity.prototype = {    main : function(node,init,detal,count,frequency){      setTimeout(function(){        if(!+"\v1"){          if(node.currentStyle.hasLayout)  node.style.zoom = 1;//防止濾鏡失效          node.style.filter="alpha(opacity="+ (init * 100 +  detal * count * 100).toFixed(1) +")"        }else{          node.style.opacity =  (init +  detal * count).toFixed(3)        }        node.innerHTML =  (init +  detal * count).toFixed(3)        count--;        if(count + 1){          setTimeout(arguments.callee, frequency);        }      },frequency)    }  }
<div class="text" onclick="new Opacity(this,{duration:4.0,from:0.0,to:1})"></div><div class="text" onclick="new Opacity(this,{duration:4.0,from:1.0,to:0})"></div>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.