網頁設計公司
您現在的位置:首頁  >  新聞中心
  • 軟體設計
    Software Development
  • 品牌及LOGO設計
    Brand and LOGO Design
  • 網站設計及建制
    Web Design
  • 多媒體動畫制作
    Multimedia Presentations
  • 聯絡我們
    Contact US
  • 新聞中心
    網頁設計公司必讀的文章 ( 91 ) 不間斷滾動圖片Javascript特效講解
    很久前在YAHOO上扣的代碼,兼容性很好,在Windows下的主流瀏覽器中可以正常運行。

    演示地址:index.html
    代碼下載:下載文件 scrollpic.rar 點擊下載此文件

    大家先不要急著下載代碼,你隨時都可以下,我們來分析下代碼(代碼中我已經寫了很詳細的註釋),要之其所以然,在解讀別人的代碼中學習提高自己,然後可以靈活運用,這個才是我將這個效果貼出來的主要目的,代碼如下:

    scrollver.js
    程序代碼 程序代碼
    scrollVertical.prototype.scrollArea=null;      // 滾動的區域
    scrollVertical.prototype.scrollMsg=null;       // 要滾動的內容
    scrollVertical.prototype.unitHeight=0;         // 單獨一行滾動內容的高度(程序中通過過的要滾動行的一個節點的offsetHeight獲得)
    scrollVertical.prototype.msgHeight=0;          // 整個滾動內容的高度
    scrollVertical.prototype.copyMsg=null;         // 複製滾動內容(程序中使用複製scrollMsg.innerHTML來獲得的)
    scrollVertical.prototype.scrollValue=0;        // 滾動的值
    scrollVertical.prototype.scrollHeight=0;       // 滾動高度
    scrollVertical.prototype.isStop=true;          // 停止滾動
    scrollVertical.prototype.isPause=false;        // 暫停滾動
    scrollVertical.prototype.scrollTimer=null;     // 滾動計時器
    scrollVertical.prototype.speed=2000;           // (默認)滾動的時間間隔2秒
    /**
    * @method isMoz - 判斷是否為Mozilla系列瀏覽器
    */
    scrollVertical.prototype.isMoz = function(){
        return navigator.userAgent.toLowerCase().indexOf('gecko') > 0;
    };
    /**
    * @method play - 滾動信息的處理方法(函數)
    * @param {Object} o - 滾動類
    */
    scrollVertical.prototype.play = function(o){
        var s_msg = o.scrollMsg;
        var c_msg = o.copyMsg;
        var s_area = o.scrollArea;
        var msg_h = o.msgHeight;
        
        var anim = function(){
            // 如果已經開始計時(間隔時間執行向上滾動),
            // 就停止它(以免無限制執行,耗系統資源)。
            if (o.scrollTimer) {
                clearTimeout(o.scrollTimer);
            }
            // 如果暫停了滾動(鼠標放到了滾動層上)
            // 開始以10毫秒的時間間隔運行滾動    
            if (o.isPause) {
                o.scrollTimer = setTimeout(anim, 10);
                return;
            }
            // 當顯示完所有信息後(這時滾動的距離就等於要滾動信息的高度msg_h)
            // 這時又重新開始滾動,將滾動距離清零
            if (msg_h - o.scrollValue <= 0) {
                o.scrollValue = 0;
            }
            else {
                o.scrollValue += 1;
                o.scrollHeight += 1;
            }
            // 根據瀏覽器的不同,處理滾動
            if (o.isMoz) { // Mozilla引擎瀏覽器
                s_area.scrollTop = o.scrollValue;
            }
            else { // 其餘的瀏覽器則使用控制CSS樣式處理滾動
                s_msg.style.top = -1 * o.scrollValue + "px";
                c_msg.style.top = (msg_h - o.scrollValue) + "px";
            }
            // 滾動高度等於顯示滾動區域高度時(滾動完一行,一行內容全部顯示)
            // 暫停4秒中,然後再開始執行下依次滾動。
            if (o.scrollHeight % s_area.offsetHeight == 0) {
                o.scrollTimer = setTimeout(anim, o.speed);
            }
            else {
                // 在兩行內容之間過度滾動時,每10豪秒上升1px
                o.scrollTimer = setTimeout(anim, 10);
            }
        };
        // 執行滾動
        anim();
    };
    /**
    * scrollVertical 垂直滾動的構造函數
    * @param {Object} disp   -  必須  顯示滾動區域的DOM節點(或節點ID)
    * @param {Object} msg    -  必須  被顯示的信息的DOM節點(或節點ID)
    * @param {string} tg     -  可選  以什麼標記為一行的標籤名稱(tagName)
    */
    function scrollVertical(disp, msg, tg){
        // 給在之前定義的this.scrollArea付值
        if (typeof(disp) == 'string') {
            // 如果disp給的是節點的ID,通過document.getElementById獲取該節點
            // 然後付值給this.scrollArea
            this.scrollArea = document.getElementById(disp);
        }
        else {
            // 如果是DOM節點,直接付給this.scrollArea
            this.scrollArea = disp;
        }
        // 以給this.scrollArea相同的方法給this.scrollMsg付值
        if (typeof(msg) == 'string') {
            this.scrollMsg = document.getElementById(msg);
        }
        else {
            this.scrollMsg = msg;
        }
        
        // 為了開發方便,
        // 不用一直寫this.scrollMsg這麼常的名字,
        // 將兩個對像付給局部變量
        var s_msg = this.scrollMsg;
        var s_area = this.scrollArea;
        
        // 如果沒有給定一行的識別標籤,
        // 默認將li標籤認為是一行的標籤
        // 所以上面介紹的,tag參數是可選的
        if (!tg) {
            var tg = 'li';
        }
        
        // 獲取單行的高度
        // 獲取到第一(s_msg.getElementsByTagName(tg)[0])tg(一行的標籤)的高度,作為單行的高度
        this.unitHeight = s_msg.getElementsByTagName(tg)[0].offsetHeight;
        // 獲取整個信息框的高度
        // 公式為 單行高度(unitHeight)*行數(s_msg.getElementsByTagName(tg).length,顯示信息中包含多少個tg(行)標籤)
        this.msgHeight = this.unitHeight * s_msg.getElementsByTagName(tg).length;
        /*
         * 複製要顯示的信息:
         * 連續滾動的實現其實就是通過複製信息,
         * 並將複製的信添加到原始信息後
         * 當原始信息滾動顯示完成,就接著滾動顯示複製的信息
         * 但給人的錯覺是,我們看到信息連續不斷的顯示
         */
        // 創建複製內容節點
        var copydiv = document.createElement('div');
        // 這個地方感覺有點嵌妥
        // 直接使用element.id的方式,不過看上去,主流的瀏覽器都支持
        // 標準的DOM Core方法:
        // copydiv.setAttribute('id',s_area.id + "_copymsgid")
        copydiv.id = s_area.id + "_copymsgid";
        // 複製原始的信息
        // 將原始的信息s_msg中的內容,直接用innerHTML寫到
        copydiv.innerHTML = s_msg.innerHTML;
        // 設置複製信息節點的高度
        copydiv.style.height = this.msgHeight + "px";
        // 將複製節點添加到原始接點(scrollMsg)後
        // 其實實現的方法就是將複製信息節點(copydiv)添家到顯示區域的節點(scrollArea)中
        s_area.appendChild(copydiv);
        
        this.copyMsg = copydiv;
        // 開始執行滾動方法
        this.play(this);
    }

    在腳本的註釋中已經說了這個效果的實現原理,而實現一個效果的關鍵就是在於運用setTimeout方法和clearTimeout方法。

    setTimeout(func,time)

    setTimeout是window對象的一個方法,所以如果要是看到這麼寫window.setTimeout你不要感到奇怪,我們平時一般都省略了window。

    setTimeout方法接受兩個參數:
    func - 在指定時間間隔內要執行的函數;
    time - 執行函數的時間間隔(以毫秒為單位,1000毫秒等於1秒)

    一開始沒有解釋setTimeout的功能,而是先說了兩個參數的意思,大家看了後就會有所瞭解,setTimeout的功能就是:設置定時器,在一段時間之後執行指定的代碼。

    不如本例中的:
    程序代碼 程序代碼
    setTimeout(anim, o.speed);


    也許你有看過類似的寫法:
    程序代碼 程序代碼
    function dosomething(){
        // do something
    }
    setTimeOout('dosomething',1000);

    建議不要這麼寫,是這樣的代碼的可讀性太差,雖然也可以正常執行。相信看到的類似的代碼也是很久前的東西了。如果還在新買的某本書中看到這樣的寫法,可能很不幸買了本爛書。現在一般我們都這麼做:
    程序代碼 程序代碼
    function whatWeDoNow(){
        var str = 'this is what we do now';
        if(doalert) {
           clearTimeout(doalert)
        }  
        var doalert = setTimeout(function(){
           alert(str);
        },1000);
    }

    而且不知道發現沒有,這麼寫還有一個好處,function還可以接受其他的參數,比如這裡可以接受whatWeDoNow()函數中的局部變量。如果再結合閉包的使用,好處會更顯而易見。

    剛才說的一點應該說是一個不好的使用setTimeout的習慣。呵呵,接下來我還要說的一個更不好的使用習慣就是只使用setTimeout()方法,而不使用clearTimeout()方法。

    clearTimeout(itimeoutid)

    clearTimeout()方法的功能是停止定時器,大家看上面的代碼:
    程序代碼 程序代碼
    clearTimeout(o.scrollTimer);

    Timer(定時器),夠直接吧。那麼為什麼要停止定時器?什麼時候停止呢?

    為什麼要停,想用個反問:能一直不停嗎,機器受得了嗎?這裡應該說說我們使用setTimeout的目的,我們通常使用它來實現像本例這樣的動畫效果。需要在很短的時間內連續不斷的執行定時器,當然它是要占資源的啊。想想,只是不斷的創建,而且往往我們做的處理,在1秒中內會執行很多次函數,一兩次還好,上百上千次,而且一個複雜些的動畫,執行很短的時間內幾萬次也不是沒有可能事情。想想,如果不在每執行完一次後,銷毀它。要是再加上定時器執行的函數又是個比較NB點的運算,寶貴的系統資源!

    所以應該向給的例子中那樣,記得在每次執行了定時器後停止(銷毀,釋放資源)它。
    程序代碼 程序代碼
    function whatWeDoNow(){
        var str = 'this is what we do now';
        if(doalert) {
           clearTimeout(doalert); // clear
        }  
        var doalert = setTimeout(function(){
           alert(str);
        },1000);
    }
    if (o.scrollTimer) {
        clearTimeout(o.scrollTimer); // clear
    }

    其實銷毀的方法很簡單,就是在每次創建定時器前,判斷是否已經創建了訂時器,就像特效例子中的
    程序代碼 程序代碼
    if (o.scrollTimer) {
        clearTimeout(o.scrollTimer); // clear
    }
    ....
    ....
    if (o.scrollHeight % s_area.offsetHeight == 0) {
        o.scrollTimer = setTimeout(anim, o.speed);
    }
    else {
        o.scrollTimer = setTimeout(anim, 10);
    }

    邏輯就是:



    是不是一個很流暢的循環?現在大家應該知道了,為什麼要clearTimeout和何時clearTimeout了嗎?

    介紹了大半天的setTimeout和clearTimeout,呵呵,現在可以看看怎麼使用這個特效吧,頁面代碼:

    程序代碼 程序代碼
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>滾動圖片</title>
    <style type="text/css">
    <!--
    *{
        margin:0;
        padding:0;
    }
    body{
        text-align:center;
        background-color:#FFF;
        color:#000;
        font:'細明體',sans-serif;
    }
    img{
        border:0;
    }
    ul,li{
        list-style-type:none;
    }
    a:link,
    a:visited{
        color:#000;
        text-decoration:none;
    }
    a:hover{
        color:#F00;
        text-decoration:none;
    }
    #container{
        margin:0 auto;
        position:relative;
        margin-top:10px;
        width:720px;
        height:100px;
        overflow:hidden;
    }
    #message,
    #message_copymsgid{
        margin:0;
        width:720px;
        overflow:hidden;
    }
    #container ul{
        float:left;
        width:720px;
        height:100px;
        overflow:hidden;
        clear:both;
    }
    #container li{
        float:left;
        text-align:center;
        width:120px;
        height:100px;
        line-height:100px;
        overflow:hidden;
        padding:0;
    }
    #container li img{
        width:96px;
        height:96px;
        margin-bottom:10px;
        padding:1px;
        border:1px solid #999;
    }
    -->
    </style>
    </head>
    <body>
    <div id="container">
    <div id="message">
    <ul><li><a href="http://www.yaohaixiao.com/" target="_blank" title="聽海"><img src="img/img1.gif" alt="聽海" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="聽海"><img src="img/img1.gif" alt="聽海" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="聽海"><img src="img/img1.gif" alt="聽海" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="聽海"><img src="img/img1.gif" alt="聽海" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="聽海"><img src="img/img1.gif" alt="聽海" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="聽海"><img src="img/img1.gif" alt="聽海" /></a></li>
    </ul>
    <ul>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="寶貝"><img src="img/img2.gif" alt="寶貝" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="寶貝"><img src="img/img2.gif" alt="寶貝" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="寶貝"><img src="img/img2.gif" alt="寶貝" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="寶貝"><img src="img/img2.gif" alt="寶貝" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="寶貝"><img src="img/img2.gif" alt="寶貝" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="寶貝"><img src="img/img2.gif" alt="寶貝" /></a></li>
    </ul>
    <ul>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="因為你"><img src="img/img3.gif" alt="因為你" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="因為你"><img src="img/img3.gif" alt="因為你" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="因為你"><img src="img/img3.gif" alt="因為你" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="因為你"><img src="img/img3.gif" alt="因為你" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="因為你"><img src="img/img3.gif" alt="因為你" /></a></li>
    <li><a href="http://www.yaohaixiao.com/" target="_blank" title="因為你"><img src="img/img3.gif" alt="因為你" /></a></li>
    </ul>
    </div>
    </div>
    <script type="text/javascript" language="javascript" src="js/event.js"></script>
    <script type="text/javascript" language="javascript" src="js/scrollver.js"></script>
    <script type="text/javascript" language="javascript">
    <!--
    function init_Scroll(){
         // 創建一個垂直滾動對象的實例
         // 顯示容器為container,你也可以直接寫document.getElement('container')
         var scrollPics = new scrollVertical('container','message','ul');
             scrollPics.speed = 4000;     // 間隔時間,更準確的說,是滾動完一行,停留的時間
             scrollPics.isPause = true;   // 是否暫停為true,不能一開始就滾動,需要先停留下,然後再滾動
        
         // 這個則是指定,第一次顯示滾動內容第一行停留的時間為2秒
         // 2秒後isPause為false,也就不暫停滾動,開始滾動了。
         // 這個時間大家可以自己設定
         var timer_start = setTimeout(function(){clearTimeout(timer_start);scrollPics.isPause = false;},2000);
         Event.addEvent(scrollPics.scrollArea,"mouseover",function(){scrollPics.isPause = true;});
         Event.addEvent(scrollPics.scrollArea,"mouseout",function(){scrollPics.isPause = false;});
    }
    /*
    * 其實這裡也可以直接寫init_Scroll();
    * 應為我已經把腳本放到文檔的最後面,
    * 在加載腳本之前,所有的DOM節點已經加載完畢
    * 已經可以直接用腳本訪問DOM節點了
    */
    Event.addEvent(window,'load',init_Scroll);
    //-->
    </script>
    </body>
    </html>

    剛才給大家介紹了JS的一些知識點,現在就講下相關的CSS技巧。
    程序代碼 程序代碼
    #container{
        margin:0 auto;
        margin-top:10px;
        width:720px;
        height:100px;
        overflow:hidden;
    }

    一定要「overflow:hidden;」,為什麼?呵呵,看看我們把高度設置為了height:100px;,正好是只一行信息的高度,如果你不overflow:hidden,在firefox也許沒有問題,它會嚴格按照你指定的高度顯示相應高度的內容,而隱藏多餘的部分(多餘的5行),而在IE中,一直就自做聰明把容器擠高,讓它把裡面的全部內容都顯示出來。而我們的效果也是只顯示一行,而隱藏多餘的5行。
    首頁 | 關於我們 | 新闻中心 | 聯絡我們 | 加入最愛
    Bay Stars Design 網頁設計公司 Copyright © 2005-2008 Bay Stars Design Web Design Company All risghts reserved.