原生JavaScript實現輪播圖


---恢復內容開始---

實現原理

通過自定義的animate函數來改變元素的left值讓圖片呈現左右滾動的效果

HTML:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="utf-8" />
 5     <link rel="stylesheet" type="text/css" href="StyleSheet.css">
 6     <title></title>
 7 </head>
 8 <body>
 9     <div id="scroll" class="scroll">
10         <div id="box" class="box">
11             <ul id="ul" style="left:-950px;">
12                 <li><img src="images/top_banner_bw01.jpg" width="950" height="438"></li>
13                 <li><img src="images/top_banner_bw02.jpg" width="950" height="438"></li>
14                 <li><img src="images/top_banner_bw03.jpg" width="950" height="438"></li>
15                 <li><img src="images/top_banner_bw04.jpg" width="950" height="438"></li>
16                 <li><img src="images/top_banner_bw05.jpg" width="950" height="438"></li>
17             </ul>
18             <ol id="olnavi"></ol>
19         </div>
20         <div id="last"></div>
21         <div id="next"></div>
22     </div>
23     <script src="a.js"></script>
24 </body>
25 </html>

CSS:

 1 body, div, p,
 2 h1, h2, h3, h4, h5, h6,
 3 dl, dt, dd, ul, ol, li,
 4 table, caption, th, td,
 5 form, fieldset, input, textarea, select,
 6 pre, address, blockquote,
 7 embed, object {
 8     margin: 0px;
 9     padding: 0px;
10 }
11 
12 ul, ol {
13     list-style:none;
14 }
15 
16 img {
17     vertical-align: top;
18 }
19 
20 .scroll {
21     width: 950px;
22     height: 438px;
23     margin: auto;
24     overflow: hidden;
25     position: relative;
26 }
27 
28 .box {
29     width: 950px;
30     height: 438px;
31     overflow: hidden;
32     position: relative;
33 }
34 
35 .box ul{
36     width: 700%;
37     position: absolute;
38     left: 0;
39     top: 0;
40     padding:0px;
41     margin:0px;
42 }
43 
44 .box ul li{
45     float: left;
46 }
47 
48 .scroll ol {
49     position: absolute;
50     right: 365px;
51     bottom: 5px;
52 }
53 
54 .scroll ol li {
55     float: left;
56     width: 20px;
57     height: 20px;
58     border-radius: 50%;
59     background: #000;
60     margin-left: 10px;
61     cursor: pointer;
62     opacity: 0.5;
63 }
64 
65 .scroll ol li.current {
66     background-color: #000099;
67     opacity: 0.8;
68 }
69 
70 #last {
71     position: absolute;
72     bottom: 179px;
73     width: 80px;
74     height: 80px;
75     cursor: pointer;
76 }
77 
78 #next {
79     position: absolute;
80     bottom: 179px;
81     right: 0px;
82     width: 80px;
83     height: 80px;
84     cursor: pointer;
85 }

JavaScript:

  1 //1.先獲取html中的元素
  2 var scroll = document.getElementById("scroll");
  3 var ul = document.getElementById("ul");
  4 var ulLis = ul.children;
  5 var liWidth = ul.children[0].offsetWidth;
  6 //2.再此之前,我們要明白,小圓點並不是寫死的,它是根據ul li中的圖片張數來決定的 。
  7 var ol = document.getElementById("olnavi");
  8 for (var i = 0; i < ulLis.length - 2; i++) {
  9     var li = document.createElement("li");
 10     li.id = (i + 1);  //id用於后面為li添加事件
 11     ol.appendChild(li);
 12     
 13 }
 14 ol.children[0].className = "current" //將第一個小圓點設置為觸發狀態
 15 //3.要實現無縫滾動 就需要多兩張圖片才行 ,即克隆第一張圖片,放到最后一張的后面,克隆最后一張,放到第一張的前面。
 16 var num = ulLis.length - 1;
 17 ul.appendChild(ul.children[0].cloneNode(true));
 18 ul.insertBefore(ul.children[num].cloneNode(true), ul.firstChild);
 19 //4.接下來為左右箭頭添加事件,鼠標放到箭頭上會變色
 20 var last = document.getElementById("last");
 21 last.style.background = "url(./img/left.png)";
 22 last.style.width = "64px";
 23 
 24 last.addEventListener("mouseenter", function () {
 25     last.style.background = "url(./img/newleft.png)";
 26 }, false);
 27 
 28 last.addEventListener("mouseleave", function () {
 29     last.style.background = "url(./img/left.png)";
 30 }, false);
 31 
 32 var next = document.getElementById("next");
 33 next.style.background = "url(./img/right.png)";
 34 next.style.width = "64px";
 35 
 36 next.addEventListener("mouseenter", function () {
 37     next.style.background = "url(./img/newright.png)";
 38 }, false);
 39 
 40 next.addEventListener("mouseleave", function () {
 41     next.style.background = "url(./img/right.png)";
 42 }, false);
 43 // 5.我們接着用js做動畫 動畫部分包括: 
 44 // ①.鼠標點擊第幾個小圓點,就要展示第幾張圖片,並且小圓點的顏色也發生變化.
 45 // ②. 鼠標點擊左右箭頭,圖片向左右移動一張
 46 // ③圖片自動輪播,(這需要一個定時器)
 47 // ④.鼠標放在圖片上,圖片停止自動播放(這需要清除定時器)
 48 // ⑤.鼠標離開圖片,圖片繼續自動輪播 (重新開始定時器) 
 49 // 這里我們封裝了一個animate()動畫函數
 50 function animate(obj, target) {  //obj為需要移動的元素,在本文中為ul,target為需要移動到的位置
 51     var speed = obj.offsetLeft < target ? 10 : -10;  //判斷速度向左還是向右
 52     obj.timer = setInterval(function () {  //計時器每隔一定時間移動一次
 53         var result = target - obj.offsetLeft;  //剩余需要移動的距離
 54         obj.style.left = obj.offsetLeft + speed + "px";  //改變元素的left來實現移動          
 55         if (Math.abs(result) <= Math.abs(speed)) {  //當需要移動的距離小於速度時
 56             clearInterval(obj.timer);   //清除計時器
 57             obj.style.left = target + "px";  //直接移動到需要移動的位置
 58             flag = true;  //將flag置為true,使點擊事件能再次觸發
 59         }
 60     }, 1);
 61 }
 62 //6.接下來把動畫函數賦給左右箭頭
 63 var flag = true;  //用於判斷上一個事件是否執行完畢,如果沒有執行完畢禁止再次觸發事件
 64 var index = 1;  //是第幾個小圓點
 65 var lastclick = function () {
 66     if (flag) {
 67         flag = false;  //進入事件將flag置為false
 68         console.log(flag);
 69         if (index === 1) {  //判斷是否為第一張
 70             index = 6;
 71             ul.style.left = "-5994px";  //當移動到第一張時,再向右移前會替換到最后一張后面的第一張,然后再向右移動。
 72             animate(ul, ul.offsetLeft + liWidth); //動畫函數一次向有移動一個圖片長度的距離
 73         }
 74         else {
 75             animate(ul, ul.offsetLeft + liWidth);
 76         }
 77         index -= 1; //移動小圓點計數器
 78         btnShow(index);  //給新的小圓點高亮,取消上一個小圓點的高亮
 79     }
 80 }
 81 last.addEventListener("click", lastclick, false);  //將函數賦給點擊事件
 82 
 83 var nextclick = function () {  //向左移與向右移類似
 84     if (flag) {
 85         flag = false;
 86         if (index === 5) {
 87             index = 0;
 88             ul.style.left = "0px";
 89             animate(ul, ul.offsetLeft - liWidth);
 90         }
 91         else {
 92             animate(ul, ul.offsetLeft - liWidth);
 93         }
 94         index += 1;
 95         btnShow(index);
 96     }
 97 }
 98 next.addEventListener("click",nextclick, false);
 99 
100 function btnShow(cur_index) {
101     for (var i = 0; i < ol.children.length; i++) {
102         ol.children[i].className = ' '; //取消全部li的類
103     }
104     ol.children[cur_index - 1].className = "current";  //給新的小圓點加上類
105 }
106 //7.再加上一個計時器,每隔一段時間就會觸發一次下一張的效果,來實現輪播
107 var timer;
108 function play() {
109     timer = setInterval(nextclick, 3000)
110 }
111 
112 scroll.addEventListener("load", play(), false);  //整個div全部加載完畢后開始
113 
114 scroll.addEventListener("mouseenter", function () { //鼠標移入圖片是清除計時器
115     clearInterval(timer);
116 }, false);
117 
118 scroll.addEventListener("mouseleave", function () {  //鼠標移出圖片時再次啟動計時器
119     play();
120 }, false);
121 
122 //8.最后給小圓點加上事件,點第幾個輪播到第幾張
123 //小圓點的點擊事件
124 var olliclick = function () {
125     if (flag) {
126         flag = false;
127         var cur_li = document.getElementsByClassName("current");
128         var lastid = cur_li[0].id;  //當前的小圓點是第幾個
129         var distance = this.id - lastid;  //計算當前小圓點與點擊的小圓點的距離(分正負)
130         if (distance == 0) {
131             flag = true;
132         }
133         else {
134             animate_ol(ul, distance);
135         }
136     }
137 }
138 
139 //給所有的小圓點添加上點擊事件
140 var ollitimer = 1
141 var lis = ol.getElementsByTagName('li');
142 for (ollitimer; ollitimer < lis.length+1; ollitimer++) {
143     var olli = document.getElementById(ollitimer);
144     olli.addEventListener("click", olliclick, false);
145 }
146 
147 function animate_ol(obj, value) {  //小圓點動畫函數
148     if (value > 0) {  //判斷移動方向
149         var speed = -20*value; //使動畫時間一致
150     }
151     if (value < 0) {
152         var speed = -20*value;
153     }
154     var lastleft = obj.offsetLeft;
155     obj.timer = setInterval(function () {
156         var distance = Math.abs(value * liWidth) - Math.abs(obj.offsetLeft - lastleft);
157         //剩余需要移動的距離
158         if (distance < Math.abs(speed)) {
159             clearInterval(obj.timer);
160             if (value > 0) {
161                 obj.style.left = obj.offsetLeft - distance + "px";
162                 flag = true;
163             }
164             if (value < 0) {
165                 obj.style.left = obj.offsetLeft + distance + "px";
166                 flag = true;
167             }
168         }
169         else {
170             obj.style.left = obj.offsetLeft + speed + "px";
171         }
172     }, 1);
173     index = index + value;
174     btnShow(index);
175 }

 再對一下常見的鬼畜bug進行一下總結:
通過設置flag來防止多次點擊造成的計時器沖突,在點擊后將flag置為false,在動畫函數結束時再置為true,這樣只能在上一個點擊事件動畫結束后才會觸發第二次。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM