[jQuery] 圖片循環向左移動(marquee效果)

[jQuery] 圖片循環向左移動(marquee效果)

一開始本來想偷懶直接用marquee元素

<!DOCTYPE html>
<html >
<head>
    <title></title>
    <style type="text/css">
        marquee
        {
            width: 450px;
        }
    </style>
</head>
<body>
    <marquee><img src="images/1.gif" alt="*" /><img src="images/2.gif" alt="*" /><img src="images/3.gif" alt="*" /></marquee>
</body>
</html>

但結果:

http://59.120.168.237/livedemo/marqueePic.html

第一張圖移動到最左邊後

image

全部圖片會消失,再瞬間從右邊往左邊移動

image

我要的是第一張圖移動到最左邊後,就讓圖片往外面移動或消失,第一張圖再回到最後一張,全部圖片再繼續左移

看來marquee的效果不符合

 

但一時間又找不到合適的jQuery marquee、slider、cycle、Carousel套件來使用,

後來想到,Head First深入淺出jQuery第五章的練習範例似乎可以拿來改

改過後的Code:

$(document).ready(function () {
 

    setTimeout(myFunc, 2000);
     

});   

var headclix = 0;

function myFunc() {
    
    if (headclix < 9) {
        $("#head").animate({ left: "-=367px" }, 500);
        headclix += 1;
    }
    else {
        $("#head").animate({ left: "0px" }, 500);
        headclix = 0;
    }

    setTimeout(myFunc, 2000);
}

 

執行結果:

http://59.120.168.237/livedemo/ch05/end/index.html

移動方式大致有照自己想的方向走,問題還是出在最後一張圖片移動完時

由於

$("#head").animate({ left: "0px" }, 500);寫法的關係

當移動完最後一張圖片後,全部圖片會往右迅速移動到初始第一張圖的位置,感覺怪怪的

後來想了想,我要的功能似乎可以自己手寫實現

 

 

 

所以馬上來測試看看

先把畫面Html代碼和CSS準備好

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        div.bannerMarquee
        {
            background-color: Gray; /*為了讓div容器明顯一點,所以弄個灰色背景色*/
            overflow: hidden; /*圖片超過容器的話,就隱藏(必填)*/
            width: 480px; /*一張圖片width:160px,此div一次呈現3張圖片,所以寬度480px*/
            height: 50px; /*一張圖片高度50px;*/
        }
        div.bannerMarquee ul
        {
            /*width: 960px; /*如果ul沒設定width的話,預設依照容器div的寬,這樣會讓li自動斷行以符合div容器範圍,為了不讓li自動斷行*/ 
            /*ul的width可以設960px(Html畫面上6張圖)*/
            margin: 0px;
            padding: 0px; /* ul預設會有margin和padding,兩者都設為0px*/
            list-style: none;
        }
        ul li
        {
            display: inline; /*讓所有的li強制在同一列(水平)*/
            float: left; /*每個li靠左對齊才不會有間隔*/
        }
        img
        {
            border-width: 0px; /* 避免img受到超連結影響出現border,所以border-width: 0px;*/
            width: 160px;
            height: 50px;
        }
    </style>
</head>
<body>
    <div class="bannerMarquee">
        <ul>
            <li><a href="#">
                <img src="images/1.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/2.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/3.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/4.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/5.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/6.gif" alt="*" /></a></li>
        </ul>
    </div>
    
</body> 
 
</html>

執行畫面:

 image

 

程式功能大概以下幾項:

1. 先把第一個li物件代碼複製一份暫存起來

2. 把剛剛複製的li 代碼附加到最後一個li元素的後面

3. 移除掉第一個li物件

4. 此功能每2秒鐘循環執行

image

先從簡單的第4點,每2秒鐘循環執行此功能

js加上以下的粗體字

<script src="scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(init);

   
   
    
    function init() {

        
        setTimeout(myFunc, 2000); //初始畫面載入後,2秒後執行myFunc()
    }

    function myFunc() {



      
     
        setTimeout(myFunc, 2000); //每2秒鐘執行myFunc()
    }

    
</script>

 

 

myFunc()內要做的事:

1. 先把第一個li物件代碼複製一份暫存起來

2. 把剛剛複製的li 代碼附加到最後一個li元素的後面

3. 移除掉第一個li物件

所以js再加上以下粗體字


<script src="scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(init);

    function init() {

        
        setTimeout(myFunc, 2000); //初始畫面載入後,2秒後執行myFunc()
    }

    function myFunc() {


        //1. 先把第一個li物件複製一份暫存起來
        var $firstLi = $("div.bannerMarquee ul li").first().clone();
        //2. 把剛剛複製的li物件附加到最後一個li元素的後面
        $("div.bannerMarquee ul li").last().after($firstLi);
        //3. 移除掉第一個li物件
        $("div.bannerMarquee ul li").first().remove();
     
        setTimeout(myFunc, 2000); //每2秒鐘執行myFunc()
    }

    
</script>

 


 
要注意的是

$("div.bannerMarquee ul li").first().clone();

要用.clone()函數

為了把第一個li的Html代碼(含li tag),附加到最後一個li,不可以用.html(),否則會

所以要用.clone();

基本上快完成了,現在執行畫面的話會發現沒有動畫效果

所以再修改$("div.bannerMarquee ul li").first().remove();

改成以下js粗體字


<script src="scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(init);

    function init() {

        
        setTimeout(myFunc, 2000); //初始畫面載入後,2秒後執行myFunc()
    }

    function myFunc() {


        //1. 先把第一個li物件複製一份暫存起來
        var $firstLi = $("div.bannerMarquee ul li").first().clone();
        //2. 把剛剛複製的li物件附加到最後一個li元素的後面
        $("div.bannerMarquee ul li").last().after($firstLi);
        //3. 移除掉第一個li物件

        //把第一個li物件先徹底隱藏後再移除掉
        $("div.bannerMarquee ul li").first().hide(500, function () {

            $(this).remove();
        });
     
        setTimeout(myFunc, 2000); //每2秒鐘執行myFunc()
    }

    
</script>

 

 

再來可能還不夠完美,如果客戶要求:

1. 當滑鼠移到圖片上時,停止動畫效果

2. 滑鼠離開圖片時,再度開始動畫效果

要做到這樣的功能,再加上以下的js代碼

(以下為完整代碼)


<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        div.bannerMarquee
        {
            background-color: Gray; /*為了讓div容器明顯一點,所以弄個灰色背景色*/
            overflow: hidden; /*圖片超過容器的話,就隱藏(必填)*/
            width: 480px; /*一張圖片width:160px,此div一次呈現3張圖片,所以寬度480px*/
            height: 50px; /*一張圖片高度50px;*/
        }
        div.bannerMarquee ul
        {
            /*width: 960px; /*如果ul沒設定width的話,預設依照容器div的寬,這樣會讓li自動斷行以符合div容器範圍,為了不讓li自動斷行*/ 
            /*ul的width可以設960px(Html畫面上6張圖)*/
            margin: 0px;
            padding: 0px; /* ul預設會有margin和padding,兩者都設為0px*/
            list-style: none;
        }
        ul li
        {
            display: inline; /*讓所有的li強制在同一列(水平)*/
            float: left; /*每個li靠左對齊才不會有間隔*/
        }
        img
        {
            border-width: 0px; /* 避免img受到超連結影響出現border,所以border-width: 0px;*/
            width: 160px;
            height: 50px;
        }
    </style>
</head>
<body>
    <div class="bannerMarquee">
        <ul>
            <li><a href="#">
                <img src="images/1.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/2.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/3.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/4.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/5.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/6.gif" alt="*" /></a></li>
        </ul>
    </div>
    
</body> 
<script src="scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(init);
    var t;
    function init() {

        $("div.bannerMarquee ul li").mouseenter(MouseEnterHandler);
        $("div.bannerMarquee ul li").mouseleave(MouseLeaveHandler);
        t=setTimeout(myFunc, 2000); //初始畫面載入後,2秒後執行myFunc()
    }

    function myFunc() {


        //1. 先把第一個li物件複製一份暫存起來
        var $firstLi = $("div.bannerMarquee ul li").first().clone();
        //2. 把剛剛複製的li物件附加到最後一個li元素的後面
        $("div.bannerMarquee ul li").last().after($firstLi);
        //3. 移除掉第一個li物件

        //把第一個li物件先徹底隱藏後再移除掉
        $("div.bannerMarquee ul li").first().hide(500, function () {

            $(this).remove();
        });
     
       t=  setTimeout(myFunc, 2000); //每2秒鐘執行myFunc()
    }
    function MouseEnterHandler() {
        clearTimeout(t);

    }

    function MouseLeaveHandler() {
    //滑鼠離開圖片2秒後,執行myFunc
        t = setTimeout(myFunc, 2000);
    }
    
</script>
</html>


 

Live Demo:http://59.120.168.237/livedemo/marqueemy.html

建議實際開發時,最好把

div.bannerMarquee
      {
            width: 480px; /*這個width拿掉好觀察元素的移動*/
      }

 

 

 

2012.4.17晚上追記

如果要一次左移三張圖片的話,可以利用slice函數一次選擇多張圖片

實現的完整代碼如下

建議ul 要設定width,因為沒設定的話,ul的寬度會跟著div容器造成預設的li會自動斷行

左移圖片時,會看到另三張圖片是在預本下方的奇怪現象

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        div.bannerMarquee
        {
            background-color: Gray; /*為了讓div容器明顯一點,所以弄個灰色背景色*/
            overflow: hidden; /*圖片超過容器的話,就隱藏(必填)*/
            width: 480px; /*一張圖片width:160px,此div一次呈現3張圖片,所以寬度480px*/
            height: 50px; /*一張圖片高度50px;*/
        }
        div.bannerMarquee ul
        {
            width: 960px; /*如果ul沒設定width的話,預設依照容器div的寬,這樣會讓li自動斷行以符合div容器範圍,為了不讓li自動斷行*/ 
            /*ul的width可以設960px(Html畫面上6張圖)*/
            margin: 0px;
            padding: 0px; /* ul預設會有margin和padding,兩者都設為0px*/
            list-style: none;
        }
        ul li
        {
            display: inline; /*讓所有的li強制在同一列(水平)*/
            float: left; /*每個li靠左對齊才不會有間隔*/
        }
        img
        {
            border-width: 0px; /* 避免img受到超連結影響出現border,所以border-width: 0px;*/
            width: 160px;
            height: 50px;
        }
    </style>
</head>
<body>
    <div class="bannerMarquee">
        <ul>
            <li><a href="#">
                <img src="images/1.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/2.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/3.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/4.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/5.gif" alt="*" /></a></li>
            <li><a href="#">
                <img src="images/6.gif" alt="*" /></a></li>
        </ul>
    </div>
    
</body> 
<script src="Scripts/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(init);
    var t;
    function init() {

        $("div.bannerMarquee ul li").mouseenter(MouseEnterHandler);
        $("div.bannerMarquee ul li").mouseleave(MouseLeaveHandler);
        t = setTimeout(myFunc, 2000); //初始畫面載入後,2秒後執行myFunc()
    }

    function myFunc() {


        //1. 先把前三個li代碼 複製暫存起來
        var $ThreeLi = $("div.bannerMarquee ul li").slice(0,3).clone();
        //2. 把剛剛複製的li物件附加到最後一個li元素的後面
        $("div.bannerMarquee ul li").last().after($ThreeLi);
        //3. 移除掉前三個li物件
        //把前三個li物件先徹底隱藏後再移除掉
        $("div.bannerMarquee ul li").slice(0, 3).hide(500, function () {

            $(this).remove(); /*這裡要注意用$(this),使用$("div.bannerMarquee ul li").slice(0, 3)會全部消失*/
        });

        t = setTimeout(myFunc, 2000); //每2秒鐘執行myFunc()
    }
    function MouseEnterHandler() {
        clearTimeout(t);

    }

    function MouseLeaveHandler() {
        //滑鼠離開圖片2秒後,執行myFunc
        t = setTimeout(myFunc, 2000);
    }
    
</script>
</html>