• 原生js实现轮播图及无缝滚动


    我这里主要说轮播图和无缝滚动的实现思路,就采用最简单的轮播图了,当然实现的思路有很多种,我这也只是其中一种。

    简单轮播图的大概结构是这样的,中间是图片,二边是箭头可以用来切换图片,下面的小圆点也可以用来切换图片。

    1.简易的轮播图效果

    先搭出html结构

     这里的左右箭头我采用的是svg图标

    1. <div class="container">
    2. <div class="carousel">
    3. <div class="item"><a href=""><img src="./3.jpg" alt="">a>div>
    4. <div class="item"><a href=""><img src="./2.jpg" alt="">a>div>
    5. <div class="item"><a href=""><img src="./1.jpg" alt="">a>div>
    6. div>
    7. <div class="left">
    8. <svg t="1693569521007" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
    9. p-id="4000" width="20" height="20">
    10. <path
    11. d="M729.6 931.2l-416-425.6 416-416c9.6-9.6 9.6-25.6 0-35.2-9.6-9.6-25.6-9.6-35.2 0l-432 435.2c-9.6 9.6-9.6 25.6 0 35.2l432 441.6c9.6 9.6 25.6 9.6 35.2 0C739.2 956.8 739.2 940.8 729.6 931.2z"
    12. p-id="4001">path>
    13. svg>
    14. div>
    15. <div class="right">
    16. <svg t="1693569535119" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
    17. p-id="4245" width="16" height="16">
    18. <path
    19. d="M761.6 489.6l-432-435.2c-9.6-9.6-25.6-9.6-35.2 0-9.6 9.6-9.6 25.6 0 35.2l416 416-416 425.6c-9.6 9.6-9.6 25.6 0 35.2s25.6 9.6 35.2 0l432-441.6C771.2 515.2 771.2 499.2 761.6 489.6z"
    20. p-id="4246">path>
    21. svg>
    22. div>
    23. <div class="indicator">
    24. <span class="active">span>
    25. <span>span>
    26. <span>span>
    27. div>
    28. div>

    然后是css样式

    1. * {
    2. margin: 0;
    3. padding: 0;
    4. box-sizing: border-box;
    5. }
    6. .container {
    7. width: 700px;
    8. height: 400px;
    9. margin: 10px auto;
    10. overflow: hidden;
    11. position: relative;
    12. }
    13. .container .carousel {
    14. width: 100%;
    15. height: 100%;
    16. display: flex;
    17. }
    18. .container .carousel .item img {
    19. width: 700px;
    20. height: 400px;
    21. }
    22. .container .indicator {
    23. height: 30px;
    24. position: absolute;
    25. bottom: 10px;
    26. left: 50%;
    27. transform: translateX(-50%);
    28. }
    29. .container .indicator span {
    30. border: 1px solid #fff;
    31. width: 20px;
    32. height: 20px;
    33. border-radius: 50%;
    34. display: inline-block;
    35. }
    36. .container .indicator span.active {
    37. background-color: pink;
    38. }
    39. .container .left {
    40. position: absolute;
    41. left: 10px;
    42. top: 50%;
    43. }
    44. .container .right {
    45. position: absolute;
    46. right: 10px;
    47. top: 50%;
    48. }

    css的关键代码是overflow:hidden,我这里开启的flex弹性盒,使用它可以将多出来的图片进行隐藏,然后其中的一个圆圈元素加上了active

     下面是js代码

    我们首先要获取到所有的dom元素

    1. var doms = {
    2. carousel: document.querySelector('.carousel'),
    3. indicator: document.querySelectorAll('.indicator span'),
    4. left: document.querySelector('.left'),
    5. right: document.querySelector('.right')
    6. }

    最重要的就是轮播的函数

    1. var curIndex = 0 //用于记录当前是第几个元素
    2. function moveTo(index) {
    3. //加上动画效果
    4. doms.carousel.style.transition = 'transform .5s'
    5. doms.carousel.style.transform = `translateX(-${index}00%)`
    6. //去除效果
    7. var active = document.querySelector('.indicator span.active')
    8. active.classList.remove('active')
    9. //选中当前效果
    10. doms.indicator[index].classList.add('active')
    11. curIndex = index
    12. }

    我这里采用的是transform的translateX(-100%)来实现的轮播切换,也可以使用margin-left来控制都可以。

    接下来可以给加上一个定时器来控制它进行自动轮播

    1. //添加图片自动轮播
    2. let timer = setInterval(() => {
    3. if (curIndex === doms.indicator.length - 1) {
    4. moveTo(0)
    5. } else (
    6. moveTo(curIndex + 1)
    7. )
    8. }, 2000)

    也可以给下面的小圆圈和左右箭头加上对应的点击事件

    1. //添加点击事件
    2. doms.indicator.forEach((item, index) => {
    3. item.addEventListener('click', () => {
    4. moveTo(index)
    5. })
    6. })
    7. //添加点击事件
    8. doms.left.addEventListener('click', () => {
    9. moveTo(curIndex-1)
    10. })
    11. doms.right.addEventListener('click', () => {
    12. moveTo(curIndex+1)
    13. })

    到这里其实已经实现的简易轮播图的基本功能,但是还并不完美,会存在防抖以及无法无缝滚动的效果

    2.无缝滚动及防抖

    无缝滚动的实现思路就是采用克隆的功能及改变动画效果来实现的

    就像这样,将最后一张复制出来放到最前面,但是展示的还是1.jpg,第一张复制放到最后面

     在切换到最后一张或者第一张时,首先将过度动画关掉切换,然后迅速开启过度动画轮播下一张,这样眼睛是无法察觉出来的,因为其速度很快。

     首先是克隆

    1. //克隆图片,实现无缝滚动
    2. function clone() {
    3. var first = doms.carousel.firstElementChild.cloneNode(true);
    4. //复制最后一张
    5. var last = doms.carousel.lastElementChild.cloneNode(true);
    6. //插入到最后
    7. doms.carousel.appendChild(first);
    8. //插入到最前
    9. doms.carousel.insertBefore(last, doms.carousel.firstElementChild)
    10. //将复制的第一张的位置调整
    11. last.style.position = 'absolute';
    12. last.style.transform = `translateX(-100%)`
    13. }
    14. clone()

    克隆的关键在于要将克隆的第一张图片改变一下位置

    然后实现右边箭头的无缝滚动

    1. //实现右边的无缝滚动
    2. var count = doms.indicator.length
    3. function rightMove() {
    4. //首先去除动画效果
    5. if (curIndex === count - 1) {
    6. doms.carousel.style.transform = `translateX(100%)`;
    7. doms.carousel.style.transition = 'none';
    8. //强制渲染,否则可能不会执行
    9. doms.carousel.clientHeight;
    10. moveTo(0)
    11. } else {
    12. moveTo(curIndex + 1)
    13. }
    14. }

    右边实现后左边就很简单了

    1. //实现左边的无缝滚动
    2. function leftMove() {
    3. if (curIndex === 0) {
    4. doms.carousel.style.transform = `translateX(-${count}00%)`;
    5. doms.carousel.style.transition = 'none';
    6. //强制渲染
    7. doms.carousel.clientHeight;
    8. moveTo(count - 1)
    9. } else {
    10. moveTo(curIndex - 1)
    11. }
    12. }

    然后我们的定时器就需要进行一下改变,让他往右边轮播‘

    1. //添加图片自动轮播
    2. let timer = setInterval(() => {
    3. rightMove()
    4. }, 2000)

    然后在需要防抖的地方进行一下防抖,其实我这种很简单的防抖就是将定时器关闭掉,在点击任务完成后再开启定时器。

    1. //添加点击事件
    2. doms.indicator.forEach((item, index) => {
    3. item.addEventListener('click', () => {
    4. //关闭定时器
    5. clearInterval(timer)
    6. moveTo(index)
    7. //执行完后开启定时器
    8. timer = setInterval(() => {
    9. rightMove()
    10. }, 2000)
    11. })
    12. })

    左右箭头的点击事件

    1. //添加点击事件
    2. doms.left.addEventListener('click', () => {
    3. //关闭定时器
    4. clearInterval(timer)
    5. leftMove()
    6. //开启定时器
    7. timer = setInterval(() => {
    8. rightMove()
    9. }, 2000)
    10. })
    11. doms.right.addEventListener('click', () => {
    12. //关闭定时器
    13. clearInterval(timer)
    14. rightMove()
    15. //开启定时器
    16. timer = setInterval(() => {
    17. rightMove()
    18. }, 2000)
    19. })

    到这里就实现了简单的轮播图效果

    整体代码:

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>Documenttitle>
    7. <style>
    8. * {
    9. margin: 0;
    10. padding: 0;
    11. box-sizing: border-box;
    12. }
    13. .container {
    14. width: 700px;
    15. height: 400px;
    16. margin: 10px auto;
    17. overflow: hidden;
    18. position: relative;
    19. }
    20. .container .carousel {
    21. width: 100%;
    22. height: 100%;
    23. display: flex;
    24. /* transition: .5s; */
    25. }
    26. .container .carousel .item img {
    27. width: 700px;
    28. height: 400px;
    29. }
    30. .container .indicator {
    31. height: 30px;
    32. position: absolute;
    33. bottom: 10px;
    34. left: 50%;
    35. transform: translateX(-50%);
    36. }
    37. .container .indicator span {
    38. /* background-color: #fff; */
    39. border: 1px solid #fff;
    40. width: 20px;
    41. height: 20px;
    42. border-radius: 50%;
    43. display: inline-block;
    44. }
    45. .container .indicator span.active {
    46. background-color: pink;
    47. }
    48. .container .left {
    49. position: absolute;
    50. left: 10px;
    51. top: 50%;
    52. }
    53. .container .right {
    54. position: absolute;
    55. right: 10px;
    56. top: 50%;
    57. }
    58. style>
    59. head>
    60. <body>
    61. <div class="container">
    62. <div class="carousel">
    63. <div class="item"><a href=""><img src="./3.jpg" alt="">a>div>
    64. <div class="item"><a href=""><img src="./2.jpg" alt="">a>div>
    65. <div class="item"><a href=""><img src="./1.jpg" alt="">a>div>
    66. div>
    67. <div class="left">
    68. <svg t="1693569521007" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
    69. p-id="4000" width="20" height="20">
    70. <path
    71. d="M729.6 931.2l-416-425.6 416-416c9.6-9.6 9.6-25.6 0-35.2-9.6-9.6-25.6-9.6-35.2 0l-432 435.2c-9.6 9.6-9.6 25.6 0 35.2l432 441.6c9.6 9.6 25.6 9.6 35.2 0C739.2 956.8 739.2 940.8 729.6 931.2z"
    72. p-id="4001">path>
    73. svg>
    74. div>
    75. <div class="right">
    76. <svg t="1693569535119" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
    77. p-id="4245" width="16" height="16">
    78. <path
    79. d="M761.6 489.6l-432-435.2c-9.6-9.6-25.6-9.6-35.2 0-9.6 9.6-9.6 25.6 0 35.2l416 416-416 425.6c-9.6 9.6-9.6 25.6 0 35.2s25.6 9.6 35.2 0l432-441.6C771.2 515.2 771.2 499.2 761.6 489.6z"
    80. p-id="4246">path>
    81. svg>
    82. div>
    83. <div class="indicator">
    84. <span class="active">span>
    85. <span>span>
    86. <span>span>
    87. div>
    88. div>
    89. body>
    90. <script>
    91. var doms = {
    92. carousel: document.querySelector('.carousel'),
    93. indicator: document.querySelectorAll('.indicator span'),
    94. left: document.querySelector('.left'),
    95. right: document.querySelector('.right')
    96. }
    97. var curIndex = 0
    98. function moveTo(index) {
    99. //加上动画效果
    100. doms.carousel.style.transition = 'transform .5s'
    101. doms.carousel.style.transform = `translateX(-${index}00%)`
    102. //去除效果
    103. var active = document.querySelector('.indicator span.active')
    104. active.classList.remove('active')
    105. //选中当前效果
    106. doms.indicator[index].classList.add('active')
    107. curIndex = index
    108. }
    109. //添加点击事件
    110. doms.indicator.forEach((item, index) => {
    111. item.addEventListener('click', () => {
    112. //关闭定时器
    113. clearInterval(timer)
    114. moveTo(index)
    115. //执行完后开启定时器
    116. timer = setInterval(() => {
    117. rightMove()
    118. }, 2000)
    119. })
    120. })
    121. //添加图片自动轮播
    122. let timer = setInterval(() => {
    123. rightMove()
    124. }, 2000)
    125. //克隆图片,实现无缝滚动
    126. function clone() {
    127. var first = doms.carousel.firstElementChild.cloneNode(true);
    128. //复制最后一张
    129. var last = doms.carousel.lastElementChild.cloneNode(true);
    130. //插入到最后
    131. doms.carousel.appendChild(first);
    132. //插入到最前
    133. doms.carousel.insertBefore(last, doms.carousel.firstElementChild)
    134. //将复制的第一张的位置调整
    135. last.style.position = 'absolute';
    136. last.style.transform = `translateX(-100%)`
    137. }
    138. clone()
    139. //实现右边的无缝滚动
    140. var count = doms.indicator.length
    141. function rightMove() {
    142. //首先去除动画效果
    143. if (curIndex === count - 1) {
    144. doms.carousel.style.transform = `translateX(100%)`;
    145. doms.carousel.style.transition = 'none';
    146. //强制渲染
    147. doms.carousel.clientHeight;
    148. moveTo(0)
    149. } else {
    150. moveTo(curIndex + 1)
    151. }
    152. }
    153. //实现左边的无缝滚动
    154. function leftMove() {
    155. if (curIndex === 0) {
    156. doms.carousel.style.transform = `translateX(-${count}00%)`;
    157. doms.carousel.style.transition = 'none';
    158. //强制渲染
    159. doms.carousel.clientHeight;
    160. moveTo(count - 1)
    161. } else {
    162. moveTo(curIndex - 1)
    163. }
    164. }
    165. //添加点击事件
    166. doms.left.addEventListener('click', () => {
    167. //关闭定时器
    168. clearInterval(timer)
    169. leftMove()
    170. //开启定时器
    171. timer = setInterval(() => {
    172. rightMove()
    173. }, 2000)
    174. })
    175. doms.right.addEventListener('click', () => {
    176. //关闭定时器
    177. clearInterval(timer)
    178. rightMove()
    179. //开启定时器
    180. timer = setInterval(() => {
    181. rightMove()
    182. }, 2000)
    183. })
    184. script>
    185. html>

     

  • 相关阅读:
    设计模式——备忘录模式(memento)
    flask自定义序列化
    [机缘参悟-77]:深度思考-职场中注意事项-管理者版
    C++ 练气期之指针所指何处
    【服务器数据恢复】MDisk重建,vdisk丢失导致数据库不可用的数据恢复案例
    数据结构-静态链表创建
    转行IC第一步:应该怎么选择公司和岗位?
    calibre和cpolar搭建一个私有的网络书库
    visual-studio-code通过跳板机连接远程服务器的配置操作
    AutoJs学习-2048全自动
  • 原文地址:https://blog.csdn.net/m0_64642443/article/details/132629979