原生JS實現無縫輪播

今天分享前端開發學習中的一個很經典的案例——原生JS實現無縫輪播圖。css

需求:前端

1.鼠標移入輪播圖時左右兩邊顯示上一頁下一頁按鈕,移出時隱藏數組

2.鼠標點擊箭頭,圖片發生輪播函數

3.點擊號碼,切換到指定圖片學習

4.鼠標移出,圖片每隔必定時間自動輪播動畫

5.當圖片輪播到最後或最前一張的時候,圖片無縫循環切換this

 

HTML頁面結構:這裏把圖片換成背景顏色了,使用時直接添加圖片路徑便可spa

 1 <div class="all" id='box'>
 2     <div class="screen">
 3         <ul>
 4             <li><img src="" width="500" height="200" style="background-color: yellowgreen;"/></li>
 5             <li><img src="" width="500" height="200" style="background-color: pink;"/></li>
 6             <li><img src="" width="500" height="200" style="background-color: skyblue;"/></li>
 7             <li><img src="" width="500" height="200" style="background-color: greenyellow;"/></li>
 8             <li><img src="" width="500" height="200" style="background-color: plum;"/></li>
 9             <li><img src="" width="500" height="200" style="background-color: orange;"/></li>
10         </ul>
11         <ol>
12             <li class="current">1</li>
13             <li>2</li>
14             <li>3</li>
15             <li>4</li>
16             <li>5</li>
17         </ol>
18 
19     </div>
20     <div id="arr"><span id="left">&lt;</span><span id="right">&gt;</span></div>
21 </div>

CSS樣式:樣式部分比較簡單,重點讓li標籤浮動並排,而後在盒子(類名爲screen的div)裏顯示其中一張,其餘的隱藏(overflow:hidden),整個輪播思想就是移動整個ul標籤。code

 1 <style type="text/css">
 2         * {
 3             padding: 0;
 4             margin: 0;
 5             list-style: none;
 6             border: 0;
 7         }
 8 
 9         .all {
10             width: 500px;
11             height: 200px;
12             padding: 7px;
13             border: 1px solid #ccc;
14             margin: 100px auto;
15             position: relative;
16         }
17 
18         .screen {
19             width: 500px;
20             height: 200px;
21             overflow: hidden;
22             position: relative;
23         }
24 
25         .screen li {
26             width: 500px;
27             height: 200px;
28             overflow: hidden;
29             float: left;
30         }
31 
32         .screen ul {
33             position: absolute;
34             left: 0;
35             top: 0px;
36             width: 3000px;
37         }
38 
39         .all ol {
40             position: absolute;
41             right: 10px;
42             bottom: 10px;
43             line-height: 20px;
44             text-align: center;
45         }
46 
47         .all ol li {
48             float: left;
49             width: 20px;
50             height: 20px;
51             background: #fff;
52             border: 1px solid #ccc;
53             margin-left: 10px;
54             cursor: pointer;
55         }
56 
57         .all ol li.current {
58             background: yellow;
59         }
60 
61         #arr {
62             display: none;
63         }
64 
65         #arr span {
66             width: 40px;
67             height: 40px;
68             position: absolute;
69             left: 5px;
70             top: 50%;
71             margin-top: -20px;
72             background: #000;
73             cursor: pointer;
74             line-height: 40px;
75             text-align: center;
76             font-weight: bold;
77             font-family: '黑體';
78             font-size: 30px;
79             color: #fff;
80             opacity: 0.3;
81             border: 1px solid #fff;
82         }
83 
84         #arr #right {
85             right: 5px;
86             left: auto;
87         }
88     </style>

JS處理:blog

第一步:完成輪播圖事件的添加 :用一個全局變量index記錄當前須要展現的圖片的索引

(1)鼠標移入移出事件:鼠標移入,顯示左右切換按鈕,移出時隱藏

(2)上一頁下一頁按鈕點擊事件點擊下一頁:index++,點擊上一頁:index--

(3)頁碼點擊事件:切換指定圖片

第二步:完成上一頁和下一頁

(1)點擊移動以前給ul添加邊界檢測:不然點擊下一頁會無限往右滾動

(2)修改當前索引(自增/自減),索引表示的是當前ul應該展現第幾張圖片

(3)移動ul(目標距離 = -index * screen的寬度)

(4)頁碼保持同步(當前顯示的是第幾張圖片,下方頁碼對應索引高亮)

第三步:完成無限輪播 核心思想:n+1

(1)常規思路:圖片滾動時,當滾動到最後一張時,咱們偷偷的快速改變ul的位置到第一張(不要動畫,瞬間改變)

  ul.style.left = '0px'; //ul回到初始位置

  index = 0; //index恢復到0

(2)問題發現:這種方式能夠實現無限輪播,可是在下一輪無限的時候第一張會被跳過去

  緣由:咱們手動改變了index爲0,而動畫又須要index+1,因此會錯過index爲0的那一張

(3)解決方案:咱們在最後一張圖片的後面加上第一張圖片(第6張)可讓用戶看到滾動效果,而後滾動到第六張時,再改變ul回到初始位置

  好處:①用戶能夠看到滾動效果,不影響體驗; ②恰好第6張與第一張是同一張圖片,快速改變位置不會形成動畫的閃現

(4)當圖片index爲最後一張的的時候,頁碼應該顯示第一個,由於最後一張和第一張是同一張圖片

第四步:完成點擊頁碼跳轉

(1)點擊的是第幾個頁碼,移動動畫的目標距離 = -index * screen.offsetWidth

(2)排他思想改變頁碼樣式

(3)頁碼的下標須要與圖片下標index保持一致,不然會產生衝突,即點擊頁碼的時候,要讓圖片下標index與頁碼下標一致

第五步:自動無限輪播

至關於每隔一段時間自動點擊下一頁按鈕,代碼邏輯徹底不變

(1)將輪播代碼封裝成一個函數

(2)開啓定時器,每隔一段時間執行這個函數

(3)鼠標移入時清除定時器,移出時開啓定時器

  1 <script>
  2     // 1.獲取頁面對應的元素
  3     var box=document.getElementById("box"); //最外部大盒子
  4     var arr=document.getElementById("arr");
  5     var screen=document.getElementsByClassName("screen")[0]; //輪播圖顯示區域div
  6     var ul=document.getElementsByTagName("ul")[0]; //顯示圖片的ul
  7     var ol=document.getElementsByTagName("ol")[0]; //顯示頁碼的ol
  8     var left=document.getElementById("left"); //上一張箭頭
  9     var right=document.getElementById("right"); //下一張箭頭
 10     var index=0; ////聲明一個變量記錄圖片的索引,默認第0張圖片
 11 
 12     //2.給box添加鼠標移入和移出事件
 13     //2.1 鼠標移入
 14     box.onmouseover= function () {
 15         arr.style.display="block"; //顯示上一頁下一頁箭頭
 16         clearInterval(timeId); //清除定時器(即鼠標移入時,圖片要中止自動輪播)
 17     };
 18     //2.2 鼠標移出
 19     box.onmouseout= function () {
 20         arr.style.display="none"; //隱藏箭頭
 21         timeId=setInterval(scroll,2000);  //重啓定時器(鼠標移出,圖片要恢復自動輪播)
 22     };
 23 
 24     //3.給上一頁下一頁箭頭添加點擊事件
 25     //3.1 下一頁,圖片向左輪播
 26     right.onclick= function () {
 27         scroll(); 
 28     };
 29     //3.2 上一頁,圖片向右輪播
 30     left.onclick= function () { 
 31         //(1)邊界檢測,若是當前已是第一張,則不作任何處理
 32         if(index==0){   
 33             //無限輪播原理:若是當前是第一張,則偷偷修改ul的位置是最後一張(第一張與最後一張是同一張圖片)
 34             index=ul.children.length-1; //index恢復到最後一張
 35             ul.style.left=-index*screen.offsetWidth+"px"; ////ul回到最後一張位置
 36         }
 37         //(2)索引自減
 38         index--;
 39          // (3)向左移動ul:目標距離 = -screen的寬度 * 索引
 40         animationMove(ul,-index*screen.offsetWidth,10);
 41         indexShow(); //同步頁碼樣式
 42     };
 43 
 44     //4.給頁碼添加點擊事件
 45     for(var i=0;i<ol.children.length;i++){
 46          //4.1 循環遍歷數組時給每個頁碼添加一個liIndex屬性記錄下標
 47         ol.children[i].liIndex=i;
 48         ol.children[i].onclick= function () {
 49             index=this.liIndex-1;
 50             scroll();
 51         };
 52     }
 53 
 54     var timeId=setInterval(scroll,2000);
 55     // 封裝一個向右輪播的函數
 56     function scroll(){
 57         //(1)邊界檢測:若是當前已是最後一張(第n+1張,n表明須要輪播的圖片數量)
 58         if(index==ul.children.length-1){
 59             //無限輪播的原理就是滾動到最後一張的時候,偷偷快速的改變ul的位置到第一張(不要任何動畫,一瞬間改變)            
 60             index=0; //index恢復到0
 61             ul.style.left=0+"px"; //ul回到初始位置
 62         } 
 63         // (2)索引自增
 64         index++; 
 65         // (3)向右移動ul:目標距離 = -screen的寬度 * 索引
 66         animationMove(ul,-index*screen.offsetWidth,10);
 67         indexShow(); //同步頁碼樣式
 68     }
 69     //5.頁碼樣式保持同步:排他思想(當前頁碼添加樣式,其餘頁碼移除該樣式)
 70     function indexShow(){
 71         for(var i=0;i<ol.children.length;i++){
 72             if(i==index){
 73                 ol.children[i].classList.add("current");
 74             }else{
 75                 ol.children[i].classList.remove("current"); 
 76             }
 77             //特殊狀況:當index爲最後一張的時候,頁碼應該顯示第一張
 78             if(index==ul.children.length-1){
 79                 ol.children[0].classList.add("current");
 80             }
 81         }
 82     }
 83     // 封裝一個滾動動畫函數
 84     function animationMove(obj,target,speed){
 85         clearInterval(obj.timeId);  //每次執行動畫先清除原有的定時器
 86         obj.timeId=setInterval(function () {
 87             var currentLeft=obj.offsetLeft; //獲取當前位置
 88            var isLeft=currentLeft>target?true:false;   //是否往左走
 89            if(isLeft){
 90                currentLeft-=10;    //往左走
 91            }else{
 92                currentLeft+=10;    //往右走
 93            }
 94            if(isLeft?currentLeft>target:currentLeft<target){
 95               obj.style.left=currentLeft+"px";  //若是當前位置不是在目標位置則進行位置處理
 96            }else{
 97                clearInterval(obj.timeId);
 98                obj.style.left=target+"px";
 99            }
100             // if(currentLeft>target){
101             //     currentLeft-=10;
102             //     obj.style.left=currentLeft+"px";
103             // }else if(currentLeft<target){
104             //     currentLeft+=10;
105             //     obj.style.left=currentLeft+"px";
106             // }else{
107             //     clearInterval(obj.timeId);
108             //     obj.style.left=target+"px";
109             // }
110         },speed);
111     }
112 </script>
相關文章
相關標籤/搜索