—恢复内容开始—

通过自定义的animate函数来改变元素的left值让图片呈现左右滚动的效果

  1. 1 <!DOCTYPE html>
  2. 2 <html>
  3. 3 <head>
  4. 4 <meta charset="utf-8" />
  5. 5 <link rel="stylesheet" type="text/css" href="StyleSheet.css">
  6. 6 <title></title>
  7. 7 </head>
  8. 8 <body>
  9. 9 <div id="scroll" class="scroll">
  10. 10 <div id="box" class="box">
  11. 11 <ul id="ul" style="left:-950px;">
  12. 12 <li><img src="images/top_banner_bw01.jpg" width="950" height="438"></li>
  13. 13 <li><img src="images/top_banner_bw02.jpg" width="950" height="438"></li>
  14. 14 <li><img src="images/top_banner_bw03.jpg" width="950" height="438"></li>
  15. 15 <li><img src="images/top_banner_bw04.jpg" width="950" height="438"></li>
  16. 16 <li><img src="images/top_banner_bw05.jpg" width="950" height="438"></li>
  17. 17 </ul>
  18. 18 <ol id="olnavi"></ol>
  19. 19 </div>
  20. 20 <div id="last"></div>
  21. 21 <div id="next"></div>
  22. 22 </div>
  23. 23 <script src="a.js"></script>
  24. 24 </body>
  25. 25 </html>
  1. 1 body, div, p,
  2. 2 h1, h2, h3, h4, h5, h6,
  3. 3 dl, dt, dd, ul, ol, li,
  4. 4 table, caption, th, td,
  5. 5 form, fieldset, input, textarea, select,
  6. 6 pre, address, blockquote,
  7. 7 embed, object {
  8. 8 margin: 0px;
  9. 9 padding: 0px;
  10. 10 }
  11. 11
  12. 12 ul, ol {
  13. 13 list-style:none;
  14. 14 }
  15. 15
  16. 16 img {
  17. 17 vertical-align: top;
  18. 18 }
  19. 19
  20. 20 .scroll {
  21. 21 width: 950px;
  22. 22 height: 438px;
  23. 23 margin: auto;
  24. 24 overflow: hidden;
  25. 25 position: relative;
  26. 26 }
  27. 27
  28. 28 .box {
  29. 29 width: 950px;
  30. 30 height: 438px;
  31. 31 overflow: hidden;
  32. 32 position: relative;
  33. 33 }
  34. 34
  35. 35 .box ul{
  36. 36 width: 700%;
  37. 37 position: absolute;
  38. 38 left: 0;
  39. 39 top: 0;
  40. 40 padding:0px;
  41. 41 margin:0px;
  42. 42 }
  43. 43
  44. 44 .box ul li{
  45. 45 float: left;
  46. 46 }
  47. 47
  48. 48 .scroll ol {
  49. 49 position: absolute;
  50. 50 right: 365px;
  51. 51 bottom: 5px;
  52. 52 }
  53. 53
  54. 54 .scroll ol li {
  55. 55 float: left;
  56. 56 width: 20px;
  57. 57 height: 20px;
  58. 58 border-radius: 50%;
  59. 59 background: #000;
  60. 60 margin-left: 10px;
  61. 61 cursor: pointer;
  62. 62 opacity: 0.5;
  63. 63 }
  64. 64
  65. 65 .scroll ol li.current {
  66. 66 background-color: #000099;
  67. 67 opacity: 0.8;
  68. 68 }
  69. 69
  70. 70 #last {
  71. 71 position: absolute;
  72. 72 bottom: 179px;
  73. 73 width: 80px;
  74. 74 height: 80px;
  75. 75 cursor: pointer;
  76. 76 }
  77. 77
  78. 78 #next {
  79. 79 position: absolute;
  80. 80 bottom: 179px;
  81. 81 right: 0px;
  82. 82 width: 80px;
  83. 83 height: 80px;
  84. 84 cursor: pointer;
  85. 85 }
  1. 1 //1.先获取html中的元素
  2. 2 var scroll = document.getElementById("scroll");
  3. 3 var ul = document.getElementById("ul");
  4. 4 var ulLis = ul.children;
  5. 5 var liWidth = ul.children[0].offsetWidth;
  6. 6 //2.再此之前,我们要明白,小圆点并不是写死的,它是根据ul li中的图片张数来决定的 。
  7. 7 var ol = document.getElementById("olnavi");
  8. 8 for (var i = 0; i < ulLis.length - 2; i++) {
  9. 9 var li = document.createElement("li");
  10. 10 li.id = (i + 1); //id用于后面为li添加事件
  11. 11 ol.appendChild(li);
  12. 12
  13. 13 }
  14. 14 ol.children[0].className = "current" //将第一个小圆点设置为触发状态
  15. 15 //3.要实现无缝滚动 就需要多两张图片才行 ,即克隆第一张图片,放到最后一张的后面,克隆最后一张,放到第一张的前面。
  16. 16 var num = ulLis.length - 1;
  17. 17 ul.appendChild(ul.children[0].cloneNode(true));
  18. 18 ul.insertBefore(ul.children[num].cloneNode(true), ul.firstChild);
  19. 19 //4.接下来为左右箭头添加事件,鼠标放到箭头上会变色
  20. 20 var last = document.getElementById("last");
  21. 21 last.style.background = "url(./img/left.png)";
  22. 22 last.style.width = "64px";
  23. 23
  24. 24 last.addEventListener("mouseenter", function () {
  25. 25 last.style.background = "url(./img/newleft.png)";
  26. 26 }, false);
  27. 27
  28. 28 last.addEventListener("mouseleave", function () {
  29. 29 last.style.background = "url(./img/left.png)";
  30. 30 }, false);
  31. 31
  32. 32 var next = document.getElementById("next");
  33. 33 next.style.background = "url(./img/right.png)";
  34. 34 next.style.width = "64px";
  35. 35
  36. 36 next.addEventListener("mouseenter", function () {
  37. 37 next.style.background = "url(./img/newright.png)";
  38. 38 }, false);
  39. 39
  40. 40 next.addEventListener("mouseleave", function () {
  41. 41 next.style.background = "url(./img/right.png)";
  42. 42 }, false);
  43. 43 // 5.我们接着用js做动画 动画部分包括: 
  44. 44 // ①.鼠标点击第几个小圆点,就要展示第几张图片,并且小圆点的颜色也发生变化.
  45. 45 // ②. 鼠标点击左右箭头,图片向左右移动一张
  46. 46 // ③图片自动轮播,(这需要一个定时器)
  47. 47 // ④.鼠标放在图片上,图片停止自动播放(这需要清除定时器)
  48. 48 // ⑤.鼠标离开图片,图片继续自动轮播 (重新开始定时器) 
  49. 49 // 这里我们封装了一个animate()动画函数
  50. 50 function animate(obj, target) { //obj为需要移动的元素,在本文中为ul,target为需要移动到的位置
  51. 51 var speed = obj.offsetLeft < target ? 10 : -10; //判断速度向左还是向右
  52. 52 obj.timer = setInterval(function () { //计时器每隔一定时间移动一次
  53. 53 var result = target - obj.offsetLeft; //剩余需要移动的距离
  54. 54 obj.style.left = obj.offsetLeft + speed + "px"; //改变元素的left来实现移动
  55. 55 if (Math.abs(result) <= Math.abs(speed)) { //当需要移动的距离小于速度时
  56. 56 clearInterval(obj.timer); //清除计时器
  57. 57 obj.style.left = target + "px"; //直接移动到需要移动的位置
  58. 58 flag = true; //将flag置为true,使点击事件能再次触发
  59. 59 }
  60. 60 }, 1);
  61. 61 }
  62. 62 //6.接下来把动画函数赋给左右箭头
  63. 63 var flag = true; //用于判断上一个事件是否执行完毕,如果没有执行完毕禁止再次触发事件
  64. 64 var index = 1; //是第几个小圆点
  65. 65 var lastclick = function () {
  66. 66 if (flag) {
  67. 67 flag = false; //进入事件将flag置为false
  68. 68 console.log(flag);
  69. 69 if (index === 1) { //判断是否为第一张
  70. 70 index = 6;
  71. 71 ul.style.left = "-5994px"; //当移动到第一张时,再向右移前会替换到最后一张后面的第一张,然后再向右移动。
  72. 72 animate(ul, ul.offsetLeft + liWidth); //动画函数一次向有移动一个图片长度的距离
  73. 73 }
  74. 74 else {
  75. 75 animate(ul, ul.offsetLeft + liWidth);
  76. 76 }
  77. 77 index -= 1; //移动小圆点计数器
  78. 78 btnShow(index); //给新的小圆点高亮,取消上一个小圆点的高亮
  79. 79 }
  80. 80 }
  81. 81 last.addEventListener("click", lastclick, false); //将函数赋给点击事件
  82. 82
  83. 83 var nextclick = function () { //向左移与向右移类似
  84. 84 if (flag) {
  85. 85 flag = false;
  86. 86 if (index === 5) {
  87. 87 index = 0;
  88. 88 ul.style.left = "0px";
  89. 89 animate(ul, ul.offsetLeft - liWidth);
  90. 90 }
  91. 91 else {
  92. 92 animate(ul, ul.offsetLeft - liWidth);
  93. 93 }
  94. 94 index += 1;
  95. 95 btnShow(index);
  96. 96 }
  97. 97 }
  98. 98 next.addEventListener("click",nextclick, false);
  99. 99
  100. 100 function btnShow(cur_index) {
  101. 101 for (var i = 0; i < ol.children.length; i++) {
  102. 102 ol.children[i].className = \' \'; //取消全部li的类
  103. 103 }
  104. 104 ol.children[cur_index - 1].className = "current"; //给新的小圆点加上类
  105. 105 }
  106. 106 //7.再加上一个计时器,每隔一段时间就会触发一次下一张的效果,来实现轮播
  107. 107 var timer;
  108. 108 function play() {
  109. 109 timer = setInterval(nextclick, 3000)
  110. 110 }
  111. 111
  112. 112 scroll.addEventListener("load", play(), false); //整个div全部加载完毕后开始
  113. 113
  114. 114 scroll.addEventListener("mouseenter", function () { //鼠标移入图片是清除计时器
  115. 115 clearInterval(timer);
  116. 116 }, false);
  117. 117
  118. 118 scroll.addEventListener("mouseleave", function () { //鼠标移出图片时再次启动计时器
  119. 119 play();
  120. 120 }, false);
  121. 121
  122. 122 //8.最后给小圆点加上事件,点第几个轮播到第几张
  123. 123 //小圆点的点击事件
  124. 124 var olliclick = function () {
  125. 125 if (flag) {
  126. 126 flag = false;
  127. 127 var cur_li = document.getElementsByClassName("current");
  128. 128 var lastid = cur_li[0].id; //当前的小圆点是第几个
  129. 129 var distance = this.id - lastid; //计算当前小圆点与点击的小圆点的距离(分正负)
  130. 130 if (distance == 0) {
  131. 131 flag = true;
  132. 132 }
  133. 133 else {
  134. 134 animate_ol(ul, distance);
  135. 135 }
  136. 136 }
  137. 137 }
  138. 138
  139. 139 //给所有的小圆点添加上点击事件
  140. 140 var ollitimer = 1
  141. 141 var lis = ol.getElementsByTagName(\'li\');
  142. 142 for (ollitimer; ollitimer < lis.length+1; ollitimer++) {
  143. 143 var olli = document.getElementById(ollitimer);
  144. 144 olli.addEventListener("click", olliclick, false);
  145. 145 }
  146. 146
  147. 147 function animate_ol(obj, value) { //小圆点动画函数
  148. 148 if (value > 0) { //判断移动方向
  149. 149 var speed = -20*value; //使动画时间一致
  150. 150 }
  151. 151 if (value < 0) {
  152. 152 var speed = -20*value;
  153. 153 }
  154. 154 var lastleft = obj.offsetLeft;
  155. 155 obj.timer = setInterval(function () {
  156. 156 var distance = Math.abs(value * liWidth) - Math.abs(obj.offsetLeft - lastleft);
  157. 157 //剩余需要移动的距离
  158. 158 if (distance < Math.abs(speed)) {
  159. 159 clearInterval(obj.timer);
  160. 160 if (value > 0) {
  161. 161 obj.style.left = obj.offsetLeft - distance + "px";
  162. 162 flag = true;
  163. 163 }
  164. 164 if (value < 0) {
  165. 165 obj.style.left = obj.offsetLeft + distance + "px";
  166. 166 flag = true;
  167. 167 }
  168. 168 }
  169. 169 else {
  170. 170 obj.style.left = obj.offsetLeft + speed + "px";
  171. 171 }
  172. 172 }, 1);
  173. 173 index = index + value;
  174. 174 btnShow(index);
  175. 175 }

 再对一下常见的鬼畜bug进行一下总结:
通过设置flag来防止多次点击造成的计时器冲突,在点击后将flag置为false,在动画函数结束时再置为true,这样只能在上一个点击事件动画结束后才会触发第二次。

版权声明:本文为mingdao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/mingdao/p/lunbo.html