[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
第一張圖移動到最左邊後
	
全部圖片會消失,再瞬間從右邊往左邊移動
	
我要的是第一張圖移動到最左邊後,就讓圖片往外面移動或消失,第一張圖再回到最後一張,全部圖片再繼續左移
看來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>
執行畫面:
	 
程式功能大概以下幾項:
1. 先把第一個li物件代碼複製一份暫存起來
2. 把剛剛複製的li 代碼附加到最後一個li元素的後面
3. 移除掉第一個li物件
4. 此功能每2秒鐘循環執行
	
先從簡單的第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>