十五分鐘用JavaScript基礎寫一個圖片輪播效果 + 思路詳解

輪播圖的基本樣式

前言

這次也是一個適合JavaScript初學者的小練手,用JavaScript的基本知識去寫一個輪播圖,其實輪播圖有很多方法去實現,像用一些框架,Bootstrap之類的,或者CSS3都可以輕松做出漂亮的輪播圖,這次去用JavaScript實現,主要是為了鍛煉自己使用Js的能力,代碼非常簡單,我會先放出HTML和CSS部分,最后詳細講解Js部分,還是那句話,重要的是思路,希望Js的初學者可以跟著我動手敲一敲,絕對對自己的能力有提升!完整代碼也放在GitHub上了,鏈接在這里:點我

效果演示:卡頓是因為GIF圖片壓縮了,損失了幀數

HTML代碼部分

 <div class="main_div">
   <div class="arrows">
         <span title="1" class="arrow"><</span>
         <span title="0" class="arrow" style="float: right">></span>
   </div>

   <ul class="ul_img">
         <li class="li_img">![](images/攝圖網-水珠在竹葉上.jpg)</li>
         <li class="li_img">![](images/攝圖網-在海邊的人.jpg)</li>
         <li class="li_img">![](images/攝圖網-清涼的荷葉.jpg)</li>
         <li class="li_img">![](images/攝圖網-綿延不絕的山嶺.jpg)</li>
   </ul>
</div>

<div style="margin-left: 600px">
         <div class="div_btn"></div>
         <div class="div_btn"></div>
         <div class="div_btn"></div>
         <div class="div_btn"></div>
</div>

整個HTML非常簡單,分三部分,第一部分就是四張圖片,第二部分就是左右方向鍵,第三部分就是底部的四個圓角矩形,沒什么說的,為了簡化代碼,都是最簡單的。

CSS代碼部分

<style>
        img {
            width: 100%;
        }

        .li_img {
            width: 800px;
            float: left;
            list-style: none;
        }

        .ul_img {
            width: 6000px;
            padding: 0px;
            margin: 0px;
            transition: all 2s;
        }

        .main_div {
            width: 800px;
            overflow: hidden;
            position: relative;
            top: 100px;
            left: 350px;
        }

        .arrows {
            z-index: 9999;
            position: absolute;
            padding-top: 230px;
            width: 800px;
        }

        .arrows span {
            font-size: 3em;
            color: seashell;
        }

        .arrows span:hover {
            /*變小手*/
            cursor: pointer;
            background-color: rgba(192, 192, 192, 0.29);
        }

        .div_btn {
            float: left;
            border-radius: 100px;
            background-color: aquamarine;
            width: 60px;
            height: 10px;
            margin-left: 10px;
            margin-top: 130px;
        }

        .div_btn:hover {
            background-color: aqua;

        }
    </style>

CSS部分也是盡量簡潔,沒有設置太花哨的樣式,隨意設置了一下,各位可以自己發揮,主要為了寫JavaScript……唯一要注意的就是我為.li_img設置了一個transition。
由于是用固定像素設置的寬高,所以不同瀏覽器可能會顯示樣式有所區別,不影響功能就是了,這里我使用調試的瀏覽器是Chrome和Firefox

JavaScript部分

請先不要直接看這部分代碼,先看我的思路講解再看這部分,你絕對可以輕松理解

<script>
    //跑動的次數
    var count = 0;
    //動畫的執行方向
    var isgo = false;
    //定義計時器對象
    var timer;
    
    window.onload = function () {
        /*獲取ul元素*/
        var ul_img = document.getElementsByClassName("ul_img")[0];
        //獲取所有的li圖片元素
        var li_img = document.getElementsByClassName("li_img");
        //獲取控制方向的箭頭元素
        var arrow = document.getElementsByClassName("arrow");
        //獲取所有按鈕元素
        var div_btn = document.getElementsByClassName("div_btn");
        div_btn[0].style.backgroundColor = "aqua";


        /*定義計時器,控制圖片移動*/
        showtime();
        function showtime() {
            timer = setInterval(function () {
                if (isgo == false) {
                    count++;
                    ul_img.style.transform = "translate(" + -800 * count + "px)";
                    if (count >= li_img.length - 1) {
                        count = li_img.length - 1;
                        isgo = true;
                    }
                }
                else {
                    count--;
                    ul_img.style.transform = "translate(" + -800 * count + "px)";
                    if (count <= 0) {
                        count = 0;
                        isgo = false;
                    }
                }

                for (var i = 0; i < div_btn.length; i++) {
                    div_btn[i].style.backgroundColor = "aquamarine";
                }
                
                div_btn[count].style.backgroundColor = "aqua";
                
            }, 4000)
        }

        /*鼠標進入左右方向鍵操作*/
        for (var i = 0; i < arrow.length; i++) {
            //鼠標懸停時
            arrow[i].onmouseover = function () {
                //停止計時器
                clearInterval(timer);
            }
            //鼠標離開時
            arrow[i].onmouseout = function () {
                //添加計時器
                showtime();
            }
            arrow[i].onclick = function () {
                //區分左右
                if (this.title == 0) {
                    count++;
                    if (count > 3) {
                        count = 0;
                    }
                }
                else {
                    count--;
                    if (count < 0) {
                        count = 3;
                    }
                }

                ul_img.style.transform = "translate(" + -800 * count + "px)";

                for (var i = 0; i < div_btn.length; i++) {
                    div_btn[i].style.backgroundColor = "aquamarine";
                }
                div_btn[count].style.backgroundColor = "aqua";
            }
        }

        //鼠標懸停在底部按鈕的操作
        for (var b = 0; b < div_btn.length; b++) {
            div_btn[b].index = b;
            div_btn[b].onmouseover = function () {

                clearInterval(timer);

                for (var a = 0; a < div_btn.length; a++) {
                    div_btn[a].style.backgroundColor = "aquamarine";
                }
                div_btn[this.index].style.backgroundColor = "aqua";
                //讓count值對應
                //為了控制方向
                if (this.index == 3) {
                    isgo = true;
                }
                if (this.index == 0) {
                    isgo = false;
                }
                count = this.index;
                ul_img.style.transform = "translate(" + -800 * this.index + "px)";
            }
            div_btn[b].onmouseout = function () {
                //添加計時器
                showtime();
            }
        }
    }
</script>

思路詳解

首先,在思考這個輪播圖怎么去實現的時候,請先考慮要為這個輪播圖設置什么樣的功能,我設定的有三個功能:

  • 圖片可以自動右向輪播,輪播至最后一張圖片的時候,反向向左輪播,循環反復
  • 可以用左右方向鍵去控制圖片輪播方向
  • 可以利用下方的圓角矩形來選擇瀏覽某一張圖片

在明確了功能之后,接下來依次解決不就行了,好,我們看第一個問題,怎么實現圖片可以自動右向輪播,輪播至最后一張圖片的時候,反向向左輪播,循環反復呢?沒錯,使用定時器setTimeout()或者setInterval()可以輕松解決,在這里我就使用setInterval(),如果有不太了解的,請點這里如何使用setInterval()。好了,接下是第一部分功能的代碼思路:

  • 第一個功能

要想讓圖片自動輪播,我們首先去設定一個函數showtime(),當然寫完了這個函數,我們的第一個功能也就完成了,好的,那我就開始寫了……



好吧,當然不能直接寫了,首先你得思考,既然圖片一開始向右輪播,你總得先設定一個方向吧,然后再考慮,還得設定一個跑動的次數,比如初始位置為第一張圖片,我要向右跑動3次,就可以到達第四張圖片,然后還要設定一個定時器對象,用處以后會說到,這幾個必須是全局變量,所以必須在一開始就聲明:

    //跑動的次數
    var count = 0;
    //動畫的執行方向
    var isgo = false;
    //定義計時器對象
    var timer;

然后可以開寫了,當然要先獲取圖片元素:

    /*獲取ul元素*/
    var ul_img = document.getElementsByClassName("ul_img")[0];
    //獲取所有的li圖片元素
    var li_img = document.getElementsByClassName("li_img");

好的,準備工作到此結束,圖片輪播的原理就是圖片排成一行,然后準備一個只有一張圖片大小的容器,對這個容器設置超出部分隱藏,在控制定時器來讓這些圖片整體左移或右移,這樣呈現出來的效果就是圖片在輪播了,我們這里先function一個showtime()函數,并在里邊添加一個定時器來為控制圖片輪播做準備:

  function showtime() {
         timer = setInterval(function (){ }, 4000);
      }

在上面,我定義了每次延遲4000毫秒(即4秒)來執行一次setInterval()里的匿名函數function(){ },是為了盡可能的讓輪播效果不至于太快。然后我在匿名函數function(){ }加入以下三行代碼:

  function showtime() {
         timer = setInterval(function (){
            if (isgo == false) {
               count++;
               ul_img.style.transform = "translate(" + -800 * count + "px)";
         }
     }, 4000);
 }

記得之前我們聲明了isgo全局變量,并為它賦值為布爾值false嗎?這里if判斷語句會直接成立,if中的語句會讓count加一,并為ul_img設置了style樣式,讓ul_img整體(即四張圖片整體的ul)向左移動800px,(因為在CSS中為圖片設置了width為800px),所以以上語句會控制圖片集體向左推入800px的距離,讓第二張圖片進入到顯示容器中,、(在此之前第二三四張圖片都是隱藏的,因為我設置了超出部分隱藏),所以此時輪播圖的狀態是第二張圖片顯示,第一三四張圖片隱藏,然后每隔4秒就會重復上述過程,然后這樣就實現了輪播……嗎?



很快你就會發現問題,那就是當向左移動了三次(即count = 3時),顯示的是第四張圖片,這沒問題對吧,但是再過4秒,可就不妙了,你會發現圖片再往左移(即 count = 4時),媽蛋!沒圖了!顯示的是空白,怎么解決呢?hin簡單!加一個if判斷語句不就行了!

  function showtime() {
         timer = setInterval(function (){
            if (isgo == false) {
               count++;
               ul_img.style.transform = "translate(" + -800 * count + "px)";
                 if (count >= li_img.length - 1) {
                        count = li_img.length - 1;
                        isgo = true;
              }
         }
     }, 4000);
 }

以上代碼,我加了一個判斷語句,在count大于等于li.img.length-1(即count >= 3)時,禁止count再自增,同時改變isgo的值,讓輪播圖開始反向滾動,所以就會在增加一個else來描述isgo=true的情況:

  function showtime() {
         timer = setInterval(function (){
        if (isgo == false) {
               count++;
               ul_img.style.transform = "translate(" + -800 * count + "px)";
                 if (count >= li_img.length - 1) {
                        count = li_img.length - 1;
                        isgo = true;
              }
         else {
                    count--;
                    ul_img.style.transform = "translate(" + -800 * count + "px)";
                    if (count <= 0) {
                        count = 0;
                        isgo = false;
                    }
              }
     }, 4000);
}
  showtime();

else的情況就是控制圖片反向輪播,所以以上代碼很好理解,就是count--,并且在count <= 0時,為isgo重新設置false,讓圖片再正向輪播,循環往復,最后再調用showtime()函數,第一個功能到此為止就完全實現了!

  • 第二個功能

第二個功能我們要添加鼠標進入左右兩個方向鍵的操作,首先獲取左右兩個方向鍵。

     //獲取控制方向的箭頭元素
     var arrow = document.getElementsByClassName("arrow");

好了,由于方向鍵有兩個,所以我們要來用for循環來為它們綁定事件:

 for (var i = 0; i < arrow.length; i++) {
      //鼠標懸停時
      arrow[i].onmouseover = function () {
      //停止計時器
      clearInterval(timer);
     }
      //鼠標離開時
      arrow[i].onmouseout = function () {
      //添加計時器
      showtime();
    }
}

以上四條語句為方向鍵綁定了兩個事件,鼠標懸停時,我們利用clearInteral()來終止定時器,這就是前面我們把timer要聲明為全局變量的原因,便于我們可以在想停止定時器的時候停止它。接下來我們為方向鍵添加onclick事件,以便我們可以通過其控制方向:

 for (var i = 0; i < arrow.length; i++) {
      //鼠標懸停時
      arrow[i].onmouseover = function () {
      //停止計時器
      clearInterval(timer);
      }
      //鼠標離開時
      arrow[i].onmouseout = function () {
      //添加計時器
      showtime();
     }
     arrow[i].onclick = function () {
     //區分左右
     if (this.title == 0) {
       count++;
      if (count > 3) {
       count = 0;
     }
    }
      else {
       count--;
      if (count < 0) {
       count = 3;
     }
    }
   ul_img.style.transform = "translate(" + -800 * count + "px)";
 }
}

不知道大家注意到了沒有,我在之前HTML中為左右方向鍵分別設置了title值:0和1;所以這里直接用title值來區分左右,為右方向鍵我們執行count++;為左方向鍵我們執行count--;同時也考慮到count>3和count<0的情況,這些之前提到過,這里不再贅述,到此為止,第二部分的功能也實現了,很簡單吧

  • 第三個功能

鼠標懸停在底部圓角矩形的操作,同樣的道理,首先獲取四個圓角矩形,然后用for循環為它們綁定事件:

     var div_btn = document.getElementsByClassName("div_btn");
     div_btn[0].style.backgroundColor = "aqua";       
     //鼠標懸停在底部按鈕的操作
     for (var b = 0; b < div_btn.length; b++) {
            div_btn[b].index = b;
            div_btn[b].onmouseover = function () {}
            div_btn[b].onmouseout = function () {}
}

有的同學可能不太懂<code>div_btn[b].index = b;</code>這條語句干什么的用的,關于這個問題,涉及到循環綁定的一個坑,請大家看這篇文章關于在for循環中綁定事件打印變量i是最后一次

好,接下來我們先寫鼠標懸停事件:

   div_btn[b].onmouseover = function () {
      clearInterval(timer);

      for (var a = 0; a < div_btn.length; a++) {
          div_btn[a].style.backgroundColor = "aquamarine";
       }
          div_btn[this.index].style.backgroundColor = "aqua";
      //為了控制方向
      if (this.index == 3) {
         isgo = true;
       }
      if (this.index == 0) {
         isgo = false;
       }
      //讓count值對應
      count = this.index;
      ul_img.style.transform = "translate(" + -800 * this.index + "px)";
    }
}

有了之前的基礎,我在講鼠標懸停事件的時候,各位應該就更容易理解了,我首先在鼠標懸停時用<code> clearInterval(timer);</code>來停止定時器,然后為每個圓角矩形都加上顏色,并且為懸停的圓角矩形變色,之后考慮到了大于三和小于零的情況,再之后,我把當前的index屬性值賦給count,讓用戶可以通過懸停底部圓角矩形來選擇看第幾張圖片。

最后再加上鼠標離開事件:

 div_btn[b].onmouseout = function () {
      //添加計時器
      showtime();
    }
}

大功告成!!!至此所有功能寫完。其實最后還有一步就是:

 for (var a = 0; a < div_btn.length; a++) {
          div_btn[a].style.backgroundColor = "aquamarine";
       }
          div_btn[count].style.backgroundColor = "aqua";
}

將以上代碼,添加到功能一和功能二的代碼里,目的是,讓圖片自動輪播和控制左右方向鍵時,底部圓角矩形也能隨之變色。
以下是源碼,放在Github上了:https://github.com/Joe19970619/Shuffling-figure-1

最后再放一遍完整的JS代碼:

<script>
    var count = 0;
    var isgo = false;
    var timer;
    
    window.onload = function () {
        var ul_img = document.getElementsByClassName("ul_img")[0];
        var li_img = document.getElementsByClassName("li_img");
        var arrow = document.getElementsByClassName("arrow");
        var div_btn = document.getElementsByClassName("div_btn");
        div_btn[0].style.backgroundColor = "aqua";


        showtime();
        function showtime() {
            timer = setInterval(function () {
                if (isgo == false) {
                    count++;
                    ul_img.style.transform = "translate(" + -800 * count + "px)";
                    if (count >= li_img.length - 1) {
                        count = li_img.length - 1;
                        isgo = true;
                    }
                }
                else {
                    count--;
                    ul_img.style.transform = "translate(" + -800 * count + "px)";
                    if (count <= 0) {
                        count = 0;
                        isgo = false;
                    }
                }
                for (var i = 0; i < div_btn.length; i++) {
                    div_btn[i].style.backgroundColor = "aquamarine";
                }     
                div_btn[count].style.backgroundColor = "aqua";
                
            }, 4000)
        }


        for (var i = 0; i < arrow.length; i++) {
            arrow[i].onmouseover = function () {
                clearInterval(timer);
            }
            arrow[i].onmouseout = function () {
                showtime();
            }
            arrow[i].onclick = function () {
                if (this.title == 0) {
                    count++;
                    if (count > 3) {
                        count = 0;
                    }
                }
                else {
                    count--;
                    if (count < 0) {
                        count = 3;
                    }
                }

                ul_img.style.transform = "translate(" + -800 * count + "px)";

                for (var i = 0; i < div_btn.length; i++) {
                    div_btn[i].style.backgroundColor = "aquamarine";
                }
                div_btn[count].style.backgroundColor = "aqua";
            }
        }
        for (var b = 0; b < div_btn.length; b++) {
            div_btn[b].index = b;
            div_btn[b].onmouseover = function () {

                clearInterval(timer);

                for (var a = 0; a < div_btn.length; a++) {
                    div_btn[a].style.backgroundColor = "aquamarine";
                }
                div_btn[this.index].style.backgroundColor = "aqua";
                if (this.index == 3) {
                    isgo = true;
                }
                if (this.index == 0) {
                    isgo = false;
                }
                count = this.index;
                ul_img.style.transform = "translate(" + -800 * this.index + "px)";
            }
            div_btn[b].onmouseout = function () {         
                showtime();
            }
        }
    }
</script>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,558評論 25 708
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,255評論 4 61
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,554評論 0 17
  • 我特別喜歡拍照,喜歡把身邊各式各樣打動我的尋常事物,用照片的形式把它們一一記錄下來,所以手機內存常常不足,需要時不...
    飛鳥630閱讀 499評論 0 0
  • 很多人新年都會有一個兩個或幾個愿望,我也有一個愿望。 小的時候有有一個愿望就是能和父母去公園,今年終于實現了我很幸...
    阿吖呆閱讀 273評論 0 0