需求文档

轮播图(焦点图)需求

    1. 做一个轮播图功能,能够循环自动轮播,当播到最后一张图片时,再播就要播第一张图片
    1. 鼠标放到轮播图窗口上,要停止自动轮播,并且左右两个小箭头要出来。点击两个小箭头可以手动切换,点击左侧的小箭头,切换上一张,点击右侧的小箭头,切换至下一张;当鼠标画出时,轮播图还要恢复自动轮播
    1. 轮播的时候下面的小点要跟着动,上面显示的第几张图片,下面第几个小点要选中
    1. 点击的这些小点,上面的图片也会跟着切换到对应的图片

轮播图的原理(左右轮播)

  1. 在外层有一个 container 的盒子,宽高只能显示一张图片,并且设置 overflow:hidden;// 溢出隐藏
  2. 在 container 下面有一个叫做 wrapper 的盒子,wrapper 相对于 container 绝对定位,wrapper 里有很多图片,这些图片尺寸都是相同的,并且在一行排列

    1. 所谓轮播:container 默认展示第一张图片(索引为0的),wrapper 的 left 值为0。当第一次轮播后,container 展示图片为第二张图片(索引为1的图片),此时 wrapper 的 left 值是负的一张图片的宽度,第二次轮播后 container 展示的第三张图片(索引为2的图片),此时 wrapper 的 left 的值是多少:负的2张图片的宽度。。。。依次类推,wrapper 的 left 的值和 container 正在展示的图片索引的关系是:wrapper 的 left 值 = -1 索引 图片宽
  3. 实现轮播:我们设置一个变量 step,默认值0,表示 container 正在展示的图片索引。 向后轮播一次,给stepIndex++,然后把 wrapper 的 left 设置成:-1 stepIndex 图片宽

轮播图的无缝轮播原理: 向 wrapper 的末尾多拼接一个第一张图片,当轮播的时候,轮播到最后一张图片时,最后这张图片和第一张图片长得一模一样,此时我们把 wrapper 的 left 的值设置成0,left 为0时,container 展示的还是第一张图片,因为设为0的这个操作特别快,给人的感觉就是无缝轮播的;

html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>轮播图左右运动版</title>
  6. <!-- IMPORT CSS -->
  7. <link rel="stylesheet" href="css/reset.min.css">
  8. <style>
  9. .container {
  10. position: relative;
  11. box-sizing: border-box;
  12. margin: 0 auto;
  13. width: 1200px;
  14. height: 240px;
  15. overflow: hidden;
  16. }
  17. .container .wrapper {
  18. position: absolute;
  19. top: 0;
  20. left: 0;
  21. box-sizing: border-box;
  22. width: 6000px;
  23. height: 100%;
  24. display: flex;
  25. }
  26. .container .wrapper .slider {
  27. box-sizing: border-box;
  28. width: 1200px;
  29. height: 100%;
  30. }
  31. .container .wrapper .slider img {
  32. width: 100%;
  33. height: 100%;
  34. }
  35. /* 分页器 */
  36. .pagenition {
  37. position: absolute;
  38. z-index: 999;
  39. bottom: 10px;
  40. left: 50%;
  41. transform: translateX(-50%);
  42. padding: 5px 10px;
  43. background: rgba(255, 255, 255, .3);
  44. font-size: 0;
  45. border-radius: 26px;
  46. }
  47. .pagenition li {
  48. display: inline-block;
  49. margin: 0 10px;
  50. width: 16px;
  51. height: 16px;
  52. border-radius: 50%;
  53. background: lightblue;
  54. cursor: pointer;
  55. }
  56. .pagenition li.active {
  57. background: lightcoral;
  58. }
  59. /* 左右按钮 */
  60. .arrow {
  61. display: none;
  62. position: absolute;
  63. z-index: 999;
  64. top: 50%;
  65. margin-top: -22.5px;
  66. width: 30px;
  67. height: 45px;
  68. background: url(images/pre.png) no-repeat 0 0;
  69. }
  70. .arrow.changeLeft {
  71. left: 0;
  72. }
  73. .arrow.changeRight {
  74. right: 0;
  75. background-position: -50px 0;
  76. }
  77. .container:hover .arrow {
  78. display: block;
  79. }
  80. </style>
  81. </head>
  82. <body>
  83. <!-- 轮播图容器 -->
  84. <div class="container">
  85. <!-- WRAPPER存放所有的图 -->
  86. <div class="wrapper">
  87. <!-- SLIDER每一个轮播图 -->
  88. <div class="slider">
  89. <img src="images/banner01.png" alt="">
  90. </div>
  91. <div class="slider">
  92. <img src="images/banner02.png" alt="">
  93. </div>
  94. <div class="slider">
  95. <img src="images/banner03.jpg" alt="">
  96. </div>
  97. <div class="slider">
  98. <img src="images/banner04.png" alt="">
  99. </div>
  100. <!-- 克隆的那份(无缝衔接) -->
  101. <div class="slider">
  102. <img src="images/banner01.png" alt="">
  103. </div>
  104. </div>
  105. <!-- PAGENATION分页器 -->
  106. <ul class="pagenition">
  107. <li class="active"></li>
  108. <li></li>
  109. <li></li>
  110. <li></li>
  111. </ul>
  112. <!-- 左右按钮 -->
  113. <a href="javascript:;" class="arrow changeLeft"></a>
  114. <a href="javascript:;" class="arrow changeRight"></a>
  115. </div>
  116. <!-- IMPORT JS -->
  117. <script src="js/jquery.min.js"></script>
  118. <script src="js/banner.js"></script>
  119. </body>
  120. </html>

js

  1. // 防抖
  2. function debounce(func, wait, immediate) {
  3. let timer = null,
  4. result = null;
  5. return function anonymous(...args) {
  6. let context = this,
  7. now = immediate && !timer;
  8. clearTimeout(timer);
  9. timer = setTimeout(() => {
  10. timer = null;
  11. !immediate ? result = func.call(context, ...args) : null;
  12. }, wait);
  13. now ? result = func.call(context, ...args) : null;
  14. return result;
  15. }
  16. }
  17. let bannerModule = (function () {
  18. let $container = $('.container'),
  19. $wrapper = $container.find('.wrapper'),
  20. $changeLeft = $container.find('.changeLeft'),
  21. $changeRight = $container.find('.changeRight'),
  22. $pagenition = $container.find('.pagenition'),
  23. $pagenitionList = $pagenition.find('li');
  24. let step = 0,
  25. autoTimer = null,
  26. interval = 1000;
  27. // 自动轮播
  28. function autoMove() {
  29. step++;
  30. if (step >= 5) {
  31. $wrapper.css('left', 0);
  32. step = 1;
  33. }
  34. $wrapper.stop().animate({
  35. left: -step * 1200
  36. }, 300);
  37. // 自动焦点对齐
  38. autoFocus();
  39. }
  40. // 自动对焦
  41. function autoFocus() {
  42. let temp = step;
  43. temp === 4 ? temp = 0 : null;
  44. $pagenitionList.each((index, item) => {
  45. let $item = $(item);
  46. if (index === temp) {
  47. $item.addClass('active');
  48. return;
  49. }
  50. $item.removeClass('active');
  51. });
  52. }
  53. // 点击焦点切换到指定的位置
  54. function handlePagenition() {
  55. $pagenitionList.click(debounce(function () {
  56. let index = $(this).index();
  57. step = index;
  58. $wrapper.stop().animate({
  59. left: -step * 1200
  60. }, 300);
  61. autoFocus();
  62. }, 300, true));
  63. }
  64. // 点击按钮处理
  65. function handleArrow() {
  66. // 右按钮处理(和自动一样)
  67. $changeRight.click(debounce(autoMove, 300, true));
  68. // 左按钮处理
  69. $changeLeft.click(debounce(function () {
  70. step--;
  71. if (step < 0) {
  72. $wrapper.css('left', -4 * 1200);
  73. step = 3;
  74. }
  75. $wrapper.stop().animate({
  76. left: -step * 1200
  77. }, 300);
  78. autoFocus();
  79. }, 300, true));
  80. }
  81. return {
  82. init() {
  83. autoTimer = setInterval(autoMove, interval);
  84. // 控制自动轮播的暂停和开始
  85. $container.on('mouseenter', () => clearInterval(autoTimer))
  86. .on('mouseleave', () => autoTimer = setInterval(autoMove, interval));
  87. // 焦点点击
  88. handlePagenition();
  89. // 按钮点击
  90. handleArrow();
  91. }
  92. }
  93. })();
  94. bannerModule.init();

左右运动的轮播图.png