天天看點

原生JS實作圖檔輪播與淡入

  最近對css的興趣提不起來,因為以前對圖檔輪播一直耿耿于懷苦于學藝不精,是以,花了點時間熟悉了一下js。然後一條道走到黑,用jquery和js寫了一下輪播和圖檔淡入的效果。以後學習的路很長,希望自己在前端的路上越走越遠`(∩_∩)′

  

  從原理來講,網上的教程有很多,簡單來說。

  

  淡入淡出,其實這裡隻用到了淡入的效果。每一張淡入的圖檔,我們将它的display設定為block,其他為none,是以實際存在并且在文檔流占位置的隻有一張圖檔。在設定圖檔的display方式之前,将圖檔的透明度逐漸增大,就會給人一種淡入的感覺。

其實在js代碼中,還有關鍵的一點,代碼中用到了閉包,是以,才對閉包有了一點點認識。在這裡多說幾句吧:

  閉包的官方”的解釋是:閉包是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。

比較簡單的說法是:

  當函數a的内部函數b被函數a外的一個變量引用的時候,就建立了一個閉包。

  說的更透徹一些。所謂“閉包”,就是在構造函數體内定義另外的函數作為目标對象的方法函數,而這個對象的方法函數反過來引用外層函數體中的臨時變量。這使得隻要目标對象在生存期内始終能保持其方法,就能間接保持原構造函數體當時用到的臨時變量值。

  盡管最開始的構造函數調用已經結束,臨時變量的名稱也都消失了,但在目标對象的方法内卻始終能引用到該變量的值,而且該值隻能通這種方法來通路。即使再次調用相同的構造函數,但隻會生成新對象和方法,新的臨時變量隻是對應新的值,和上次那次調用的是各自獨立的。

  下面這個函數就是一個閉包函數。為什麼要用閉包?普通函數不可以嗎?真的是不可以。這裡閉包的作用是保持對flag的引用。如果不用閉包,對于局部變量來說,隻要函數執行了一次,也就是flag執行了一次,這個局部變量就會被垃圾回收機制回收清理掉,而我們通過間歇調用中的函數引用flag變量,在第二次執行的時候,flag就會失去它的值,函數體無法執行正确的結果了。在開始接觸前端的時候,覺得閉包可有可無,事實是,這東西真的很重要!

var setVal = function(s, flag)
        {
            return function()
            {
                pos = Math.abs(parseInt(pic.style[point]));
                if(flag > ){      //目前點大于目标點坐标,畫面向右移動,left值減小
                    pic.style[point] =-Math.floor(pos+(parseInt(s*sSingleSize) - pos)*speed) +'px';
                }
                if(flag < ) {
                    pic.style[point] =-Math.ceil(pos+(parseInt(s*sSingleSize) - pos)*speed) +'px';
                }
                if(pos == (sSingleSize * s))
                {
                    now = s;
                    clearInterval(interval);
                }
            }
        };
           

下面是代碼:

html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>picsGlide</title>
<link href="css/index.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="js/jquery-1.3.2.js"></script>

<script src="js/index.js"></script>
</head>
<body onLoad="init()">
<div id = "picBox">
    <ul class = "show_pic" style = "left: 0">
        <li class = "on"><a href="#"><img src="imgs/ccc.jpg" alt="" title="" /></a></li>
        <li><img src="imgs/aaa.jpg" alt="" title="" /></li>
        <li><img src="imgs/bbb.jpg" alt="" title="" /></li>
        <li><img src="imgs/ccc.jpg" alt="" title="" /></li>
        <li><img src="imgs/ccc.jpg" alt="" title="" /></li>
    </ul>
    <div class = "bg"></div> 
    <ul class = "show_des">
        <li class="on">puss in boots1</li> 
        <li>puss in boots2</li> 
        <li>puss in boots3</li> 
        <li>puss in boots4</li> 
        <li>puss in boots5</li> 
    </ul> 
    <ul class = "icon_num">
        <li class = "on" >1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
</div>

</body>
</html>
           

css

body {font-size: px; 
}
ul, li {
    padding: ;
    margin: ;
    list-style: none; 
}
#picBox {
    width: px; 
    height: px; 
    margin: px auto; 
    overflow: hidden; 
    position: relative;
    font-size: ;
}
/*輪播圖檔*/
#picBox .show_pic {
    width: px;
    position: absolute;
}
#picBox .show_pic li {
    float: left; 
    width: px; 
    height: px;
    display: none;
    /*display: none;
*/
}
#picBox .show_pic li.on { 
    display: block;
}
#picBox .show_pic li img { 
    display: block;
    width: px;
    height: px;
}
#picBox .icon_num {
    position: absolute;
    bottom: px; 
    right: px;
    z-index: ;

}
#picBox .icon_num li { 
    float: left; 
    /*background: url(/uploadfile/200912/28/FA15567738.gif) no-repeat -15px 0;
    */
    width: px; 
    height: px;
    font-size: px; 
    color: #39F; 
    text-align: center;  
    cursor: pointer; 
    margin-right: px;
}

#picBox .icon_num li.on {
    background: #000;
    opacity: ; 
}
/*背景*/
.bg {
    z-index: ;
    position: absolute;
    bottom: ;
    height: px;
    width: px;
    background: #000;
    opacity: ;
    filter: alpha(opacity = );
}
#picBox .show_des {
    width: px;
    height: px;
    position: absolute;
    bottom: px;
    left: px;
    color: #fff;
    z-index: ;
}
#picBox .show_des li {
    display: none;
    line-height: px;
    font-size: px;
}
#picBox .show_des li.on { 
    display: block;
}

           

js

function cleanWhitespace(oEelement)
    {
        for(var i=;i<oEelement.childNodes.length;i++){
            var node=oEelement.childNodes[i];
            if(node.nodeType== && !/\S/.test(node.nodeValue))
            {
                node.parentNode.removeChild(node);
            }
        }
    }
    //輪播代碼
    this.layerGlide=function(auto,oBox,sSingleSize,second,fSpeed,point)
    {
        var interval,timeout;        //兩個定時器
        var pos;                     //目前定位坐标整形的絕對值
        var time = second, now = ;       //time圖檔移動一次時間間隔, now目前圖檔的index值
        var speed = fSpeed           //移動速度
        var delay = second * ;   //每次切換圖檔的時間間隔

        var picBox = document.getElementById(oBox);
        cleanWhitespace(picBox);
        var pic = picBox.childNodes[]; //圖檔清單
        var des = picBox.childNodes[].getElementsByTagName("li"); //圖檔清單
        var con = picBox.childNodes[].getElementsByTagName("li");
        var sum = con.length;
        var setVal = function(s, flag)
        {
            return function()
            {
                pos = Math.abs(parseInt(pic.style[point]));
                if(flag > ){      //目前點大于目标點坐标,畫面向右移動,left值減小
                    pic.style[point] =-Math.floor(pos+(parseInt(s*sSingleSize) - pos)*speed) +'px';
                }
                if(flag < ) {
                    pic.style[point] =-Math.ceil(pos+(parseInt(s*sSingleSize) - pos)*speed) +'px';
                }
                if(pos == (sSingleSize * s))
                {
                    now = s;
                    clearInterval(interval);
                }
            }
        };
        var changeTo = function(num) {
            for(var i=; i<sum; i++)
            {
                con[i].className = "";
                des[i].className = ""; 
            };
            con[num].className = "on";
            des[num].className = "on";
            var flag = Math.abs(parseInt(pic.style[point]))-sSingleSize * num ;
            interval = setInterval(setVal(num, flag), time);
           //bkg.hide().fadeIn();
        } 
        function autoGlide()
        {
            clearTimeout(interval);
            now = (now == (parseInt(sum)-) )? : (now + );
            changeTo(now);
            timeout = setTimeout(autoGlide,delay);
        }
        function isAuto() {
            if(auto) {
                timeout = setTimeout(autoGlide,delay);
            };
        }
        isAuto();    //開始自動輪播
        for(var i=; i<sum; i++)    //導航按鈕
        {
            con[i].onmouseover = (function(i)
            {
                return function()
                {
                    clearTimeout(timeout);
                    clearInterval(interval);
                    changeTo(i);
                    this.onmouseout=isAuto();
                }
            })(i)
        }
    }
           
//淡入淡出
    this.layerFader=function(auto, oBox, second, count, speed)
    {
        var interval,timeout;        //兩個定時器
        var now = ;       //time圖檔移動一次時間間隔, now目前圖檔的index值
        var delay = second * ;   //每次切換圖檔的時間間隔

        var picBox = document.getElementById(oBox);
        cleanWhitespace(picBox);
        var pic = picBox.childNodes[].getElementsByTagName("li");
        var des = picBox.childNodes[].getElementsByTagName("li"); 
        var con = picBox.childNodes[].getElementsByTagName("li");
        var sum = con.length;

        function fadeIn(elem){    
            setOpacity(elem,); //初始全透明
            for(var i = ;i<=count;i++){ //透明度改變 20 * 5 = 100     
                (function(i){        
                     var level = i * ;  //透明度每次變化值      
                     setTimeout(function(){          
                         setOpacity(elem, level)       
                     },i*speed); 
                 })(i);     
            } 
        }   
        function setOpacity(elem, level) {    //設定透明度 
            if (elem.filters) {
                elem.style.filter = "alpha(opacity=" + level + ")";
            } else {
                elem.style.opacity = level / ;
            }
        }
        var changeTo = function(num) {
            for(var i=; i<sum; i++)
            {
                con[i].className = "";
                des[i].className = ""; 
                pic[i].className = "";
            };
            fadeIn(pic[num]);
            con[num].className = "on";
            des[num].className = "on";
            pic[num].className = "on";
           //bkg.hide().fadeIn();
        } 
        function autoGlide()
        {
            clearTimeout(interval);
            now = (now == (parseInt(sum)-) )? : (now + );
            changeTo(now);
            timeout = setTimeout(autoGlide,delay);
        }
        function isAuto() {
            if(auto) {
                timeout = setTimeout(autoGlide,delay);
            };
        }
        isAuto();    //開始自動輪播
        for(var i=; i<sum; i++)    //導航按鈕
        {
            con[i].onmouseover = (function(i)
            {
                return function()
                {
                    clearTimeout(timeout);
                    //clearInterval(interval);
                    changeTo(i);
                    this.onmouseout=isAuto();
                }
            })(i)
        }
    }
           

jquery相對于js就簡單了很多,這裡就不贅述了。大三的時候上設計模式課,老師告訴我們針對接口而不是針對實作程式設計,代碼中盡量不要出現常量,提高代碼的複用性,是以寫代碼的時候,把可變的因素都提到了參數中。最後一句,對于js的DOM操作,js原生是王道,多用多練,才能掌握的好,希望以後越走越遠。

繼續閱讀