PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

博客列表 > 原生ES6 js module实现防淘宝轮播图 (附源码)

原生ES6 js module实现防淘宝轮播图 (附源码)

高空中的云
高空中的云 原创
2022年11月20日 13:01:09 513浏览

在样例的基础上添加了左右点击的按钮和事件

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>实战: 仿淘宝移动端轮播图-模块</title>
  8. <link rel="stylesheet" href="static/css/slideshow.css" />
  9. </head>
  10. <body>
  11. <div class="slideshow">
  12. <!-- 1. 图片容器 -->
  13. <div class="imgs"></div>
  14. <!-- 2. 按钮容器 -->
  15. <div class="btns"></div>
  16. <!-- 3. 居中左右播放按钮 -->
  17. <div class="midBtns"></div>
  18. </div>
  19. <script type="module">
  20. // 1. 获取图片容器和按钮容器
  21. const imgs = document.querySelector('.imgs');
  22. const btns = document.querySelector('.btns');
  23. const midBtns = document.querySelector('.midBtns');
  24. // console.log(imgs, btns);
  25. // 2. 导入轮播图模块
  26. // (1) 创建图片组: createImgs()
  27. // (2) 创建按钮组: createBtns()
  28. // (3) 创建按钮事件: switchImg()
  29. // (4) 定时器: timePlay()
  30. import { createImgs, createBtns, switchImg, timePlay,createArrows,lrswitchImg } from './static/js/slideshow.js';
  31. // 简化方案例, 使用一个对象来挂载所有导出成员(命名空间方式)
  32. // import * as slideshow from './static/js/slideshow.js';
  33. // 3. 加载成功将图片以及按钮渲染出来
  34. window.onload = () => {
  35. // (1) 创建图片组
  36. createImgs(imgs);
  37. // (2) 创建按钮组
  38. createBtns(imgs, btns);
  39. // 创建中间左右按钮
  40. createArrows(midBtns);
  41. // 事件委托不能滥用,将点击事件绑定到每一个按钮上
  42. // (3) 创建按钮事件
  43. [...btns.children].forEach(function (btn) {
  44. btn.onclick = function () {
  45. switchImg(this, imgs);
  46. };
  47. });
  48. [...midBtns.children].forEach(function (btn){
  49. btn.onclick = function (){
  50. lrswitchImg(this,imgs,btns);
  51. }
  52. })
  53. // [...btns.children].forEach(btn => (btn.onclick = () => switchImg(this, imgs)));
  54. // (4) 定时器: timePlay()
  55. // 0,1,2
  56. // 1,2,0
  57. // 2,0,1
  58. // 0,1,2
  59. // 必须首尾相连,才能实现循环重复播放
  60. // 按钮数组,三个span
  61. const btnArr = [...btns.children];
  62. console.log(btnArr);
  63. // 按钮索引的数组
  64. const btnKeys = Object.keys(btns.children);
  65. console.log(btnKeys);
  66. setInterval(
  67. function (btnArr, btnKeys) {
  68. timePlay(btnArr, btnKeys);
  69. },
  70. 2000,
  71. btnArr,
  72. btnKeys
  73. );
  74. };
  75. </script>
  76. </body>
  77. </html>
  1. body {
  2. background-color: #eee;
  3. }
  4. .midBtns {
  5. position: relative;
  6. display: grid;
  7. grid-template-columns: 1fr 1fr;
  8. top: -220px;
  9. padding: 0 10px;
  10. }
  11. .previous,
  12. .next {
  13. width: 50px;
  14. height: 50px;
  15. background-size: contain;
  16. background-repeat: no-repeat;
  17. background-position: center;
  18. }
  19. .previous {
  20. background-image: url('../images/left.png');
  21. }
  22. .next {
  23. background-image: url('../images/right.png');
  24. place-self: end;
  25. }
  26. /* 轮播图容器 */
  27. .slideshow {
  28. width: 240px;
  29. height: 360px;
  30. }
  31. /* 图片容器 */
  32. .slideshow .imgs {
  33. width: inherit;
  34. height: inherit;
  35. }
  36. /* 图片适应 */
  37. .slideshow img {
  38. width: 100%;
  39. height: 100%;
  40. border-radius: 10px;
  41. /* 默认全隐藏 */
  42. display: none;
  43. }
  44. /* 设置图片的激活状态 */
  45. .slideshow img.active {
  46. display: block;
  47. }
  48. .slideshow img:hover {
  49. cursor: pointer;
  50. }
  51. /* ------ 按钮容器 ------- */
  52. /* 按钮容器 */
  53. .slideshow .btns {
  54. display: flex;
  55. place-content: center;
  56. /* position: relative;
  57. top: -40px; */
  58. transform: translateY(-40px);
  59. }
  60. .slideshow .btns > span {
  61. background-color: rgba(233, 233, 233, 0.5);
  62. height: 16px;
  63. width: 16px;
  64. border-radius: 50%;
  65. margin: 5px;
  66. }
  67. .slideshow .btns > span.active {
  68. background-color: orangered;
  69. }
  70. .slideshow .btns > span:hover {
  71. cursor: pointer;
  72. }
  1. // todo 轮播图模块
  2. // * 1. 图片组
  3. const imgArr = [
  4. {
  5. key: 1,
  6. src: 'static/images/item1.jpeg',
  7. url: 'https://php.cn',
  8. },
  9. {
  10. key: 2,
  11. src: 'static/images/item2.jpeg',
  12. url: 'https://php.cn',
  13. },
  14. {
  15. key: 3,
  16. src: 'static/images/item3.jpeg',
  17. url: 'https://php.cn',
  18. },
  19. ];
  20. // * 2. 创建图片组
  21. function createImgs(imgs) {
  22. // 图片资源比较大,所以建议用文档片断来做
  23. const frag = new DocumentFragment();
  24. for (let i = 0; i < imgArr.length; i++) {
  25. // 1. 创建图片元素
  26. // const img = document.createElement('img')
  27. const img = new Image();
  28. // 2. 添加属性
  29. // src
  30. img.src = imgArr[i].src;
  31. // data-key
  32. img.dataset.key = imgArr[i].key;
  33. // class='active': 第一张
  34. if (i === 0) img.classList.add('active');
  35. // 3. 添加事件
  36. img.onclick = () => (location.href = imgArr[i].url);
  37. // 添加图片分二步: 第一步加到内存中的文档片断元素上, 第二步再加到图片容器上
  38. // 4. 添加图片到片断中
  39. frag.append(img);
  40. }
  41. // 5. 将片断添加到图片容器元素中
  42. imgs.append(frag);
  43. }
  44. // * 3. 创建按钮组
  45. function createBtns(imgs, btns) {
  46. // 计算出所有图片的数量,根据这个来创建相同数量的按钮
  47. // console.log(imgs.childElementCount);
  48. let length = imgs.childElementCount;
  49. for (let i = 0; i < length; i++) {
  50. // 1. 生成按钮: <span>
  51. const btn = document.createElement('span');
  52. // 2. 按钮索引: data-key, 必须与图片索引一致
  53. btn.dataset.key = imgs.children[i].dataset.key;
  54. // 3. 第1个按钮处于激活状态
  55. if (i === 0) btn.classList.add('active');
  56. // 4. 添加到容器中
  57. btns.append(btn);
  58. }
  59. }
  60. // * 4. 按钮点击事件
  61. function switchImg(btn, imgs) {
  62. // 1. 去掉图片和按钮的激活状态
  63. [...btn.parentNode.children].forEach(btn => btn.classList.remove('active'));
  64. [...imgs.children].forEach(img => img.classList.remove('active'));
  65. // 2. 将当前的按钮处于激活状态
  66. btn.classList.add('active');
  67. // 3. 根据按钮索引,找到对应的图片
  68. const currImg = [...imgs.children].find(function (img) {
  69. return img.dataset.key == btn.dataset.key;
  70. });
  71. // const currImg = [...imgs.children].find(img => img.dataset.key == btn.dataset.key);
  72. // console.log(currImg);
  73. // 4. 将当前图片处于激活状态(显示出来)
  74. currImg.classList.add('active');
  75. }
  76. // * 5. 定时播放
  77. function timePlay(btnArr, btnKeys) {
  78. // 1. 头部取一个
  79. let key = btnKeys.shift();
  80. // 2. 根据索引找到对应的按钮,再给它自动派发一个点击事件
  81. btnArr[key].dispatchEvent(new Event('click'));
  82. // 3. 把刚才到出的按钮再从尾部进入,实现首尾相连
  83. btnKeys.push(key);
  84. }
  85. // * 6. 创建中间的按钮
  86. function createArrows(midBtns){
  87. const previous = document.createElement('span');
  88. previous.classList.add('previous');
  89. const next = document.createElement('span');
  90. next.classList.add('next');
  91. // 添加到容器中
  92. midBtns.append(previous);
  93. midBtns.append(next);
  94. }
  95. // * 7. 中间按钮(点击左右翻动轮播图)
  96. function lrswitchImg(btn,imgs,botbtns){
  97. let length = imgs.childElementCount;
  98. // 1. 获取当前active状态的图片和按钮
  99. // const imgs = document.querySelectorAll('img');
  100. // console.log(imgs);
  101. const activeImg = [...imgs.children].find(function (img) {
  102. // 去掉图片和按钮的激活状态
  103. if(img.classList.contains('active')){
  104. img.classList.remove('active');
  105. return img;
  106. }
  107. })
  108. ;[...botbtns.children].find(function (btn) {
  109. // 去掉按钮的激活状态
  110. if(btn.classList.contains('active')){
  111. btn.classList.remove('active');
  112. }
  113. })
  114. let index = activeImg.dataset.key;
  115. // 判断当前按钮是previous还是next,
  116. // next:当前索引+1,如到最后一个,则返回第0个
  117. if(btn.classList.contains('next')){
  118. index++;
  119. if(index > length){
  120. index = 1;
  121. }
  122. }
  123. // previous: 当前索引-1,如到第一个,则返回最后一个
  124. if(btn.classList.contains('previous')){
  125. if(index > 1){
  126. index--;
  127. }else{
  128. index = length;
  129. }
  130. }
  131. console.log(index);
  132. // 将当前图片设为active
  133. // 3. 根据按钮索引,找到对应的图片和底部按钮
  134. const currImg = [...imgs.children].find(function (img) {
  135. return img.dataset.key == index;
  136. });
  137. const currBtn = [...botbtns.children].find(function (btn) {
  138. return btn.dataset.key == index;
  139. });
  140. // const currImg = [...imgs.children].find(img => img.dataset.key == btn.dataset.key);
  141. // console.log(currImg);
  142. // 4. 将当前图片处于激活状态(显示出来)
  143. currImg.classList.add('active');
  144. currBtn.classList.add('active');
  145. }
  146. export { createImgs, createBtns, switchImg, timePlay,createArrows,lrswitchImg};
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议