• 37.轮播图


    目录

    1  左右按钮显示与隐藏

    2  动态生成索引li

    3  左右按键无缝滚动原理

    4  克隆最后一张图像

    5  li的检测

    6  li的点击功能

    7  右键点击功能

    8  左键点击功能

    9  自动播放功能

    10  节流阀

    11  源码


    先把结构搞好

    一共三张轮换图像,调整的差不多后将后两张图像隐藏起来

    html

    1. html>
    2. <html lang="en">
    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>Documenttitle>
    8. <link rel="stylesheet" href="轮播图.css">
    9. head>
    10. <body>
    11. <div class="rotate">
    12. <div class="content">
    13. <a href="#"><img src="upload/1.jpeg" alt="">a>
    14. <a href="#"><img src="upload/2.jpeg" alt="">a>
    15. <a href="#"><img src="upload/3.jpeg" alt="">a>
    16. div>
    17. <div class="left">div>
    18. <div class="right">div>
    19. <ul class="bottom">
    20. <li class="current">li>
    21. <li>li>
    22. <li>li>
    23. ul>
    24. div>
    25. body>
    26. html>

    css

    1. * {
    2. margin: 0px;
    3. padding: 0px;
    4. box-sizing: content-box;
    5. }
    6. li {
    7. list-style: none;
    8. }
    9. .rotate {
    10. position: relative;
    11. left:50%;
    12. transform: translate(-50%,0);
    13. width:500px;
    14. height:300px;
    15. overflow: hidden;
    16. }
    17. .content {
    18. width:300%;
    19. height:100%;
    20. display: flex;
    21. }
    22. .content a {
    23. width:100%;
    24. height:100%;
    25. }
    26. .content img {
    27. width:100%;
    28. height:100%;
    29. z-index: -1;
    30. }
    31. .left,.right {
    32. position:absolute;
    33. top:50%;
    34. transform: translate(0,-50%);
    35. width:23px;
    36. height:43px;
    37. /* background-color: red; */
    38. }
    39. .left {
    40. left:0px;
    41. background-image:url(images/border_left.png);
    42. }
    43. .right {
    44. right:0px;
    45. background-image:url(images/border_right.png);
    46. }
    47. .bottom {
    48. position: absolute;
    49. bottom:0px;
    50. left:50%;
    51. transform: translate(-50%,0);
    52. display: flex;
    53. align-items: center;
    54. justify-content: space-around;
    55. width:100px;
    56. height:20px;
    57. }
    58. .bottom li {
    59. width:10px;
    60. height:10px;
    61. background-color:white;
    62. border-radius: 5px;
    63. }
    64. .bottom .current {
    65. background-color: skyblue;
    66. }

    轮播图主要有下面几个功能

    • 左右按钮
      • 当鼠标进入轮播图后,按钮处于显示状态,离开后处于隐藏状态
      • 左右按键可以用动画效果切换不同轮播图
    • 下面的三个li
      • 第一张图被展示,那么第一个li的样式就与其他的li不同
      • 点击任意一个li可以按索引切换不同的图像
    • 轮播图本身
      • 当鼠标不在轮播图内,轮播图自动播放,离开轮播图后,轮播图停止播放

    还有其他一些需要改进的地方,我随着就写了

    讲解轮播图的视频为P317-P328 06-网页轮播图-结构搭建_哔哩哔哩_bilibili

    我与视频中的方法略有不同

    1  左右按钮显示与隐藏

    2  动态生成索引li

    先数出来有几张轮播图,只会再添加几个li,最后把第一个li设置为current

    效果与之前相同

    3  左右按键无缝滚动原理

    我们像让轮播图切换到最后一张图像的时候,之后无缝切换到第一张,这个时候我们需要在content的最后克隆第一张轮播图,这样我们就可以做出由3号滚动到1号的效果

    • 黑色框为可视区域

    在我们滚动到新克隆的1的时候,不使用动画直接把content的位置搞到第一张

    由于两张图像完全一样,所以人眼不会分辨出来

    上面是向右边滚的情况,从右往左滚也是一样

    我们现在在2这里

    由于是向左滚,我们正常滚到1

    滚到1之后直接瞬移到克隆出来的1

    这样就可以正常滚到3了

    下面的代码我就与课程上写的不一样的,感兴趣的话可以看一下课程

    4  克隆最后一张图像

    克隆这张图像没什么好说的,这里注意我li_num是在克隆之前获取的,并且没有再次赋值li_num,所以我li_num就是图像的数量

    5  li的检测

    我通过 移动的位置与图像的宽度判断li的位置,比如0就是第0个li,-500就是第一个li。我现在有3张图像,就有3个li,它们的编号依次是0,1,2

    由于要做到无缝滚动,所以我们要考虑两个例外

    第一个例外是我 从左到右 滚动到 我新克隆出来的图像1,也就是current_li_index为3的时候,当从左到右滚动到克隆1时,我的li的编号要为0

    第二个例外是我 从右到左 滚动到 我新克隆出来的图像1,也就是current_li_index为-1的时候,当从右到左滚动到克隆1时,我的li的编号要为0

    • 可以用逻辑或写在一起,我这里这样写比较方便理解

    之后做了一个排他

    最后 每15ms检测一次li的位置,并随位置的变化而变化

    6  li的点击功能

    我们点击li要能切换到指定的图像,方法是给每一个li一个位置属性,然后点哪个li,就移动到对应的位置

    7  右键点击功能

    首先右键点击功能与自动播放功能是一样的,点击需要点一下,自动播放不需要点,所以我搞了一个函数方便后面复用

    这里首先拿到两个位置,第一个位置是克隆1的位置,第二个位置是第三张图像的位置,因为向右点击要做无缝切换,这两个位置就是例外

    下面我们进行一个判断,判断条件是(1000,1500]

    注意我这里是先判断,在执行动作,在3->克隆1执行后,位置正好是1000,不满足判断条件

    也就是说我这个判断条件只会 出现 在 克隆1->3的情况

    如果我不加这个判断,它就会从 克隆1回滚到2,加了之后,在克隆1的时候,然后点击右键,依然会滚动到-500,但在克隆1时满足判断条件,所以会先瞬移会图像1,然后滚动倒-500

    之后当前li的索引自加,然后进行判断(这里可以不用判断,为了与左键点击代码对称所以加了一下),这里的判断意思是,如果当前li的索引右溢出,将distance置于克隆1位置,其余情况照常

    最后播放动画,函数外添加点击事件

    8  左键点击功能

    与右键点击功能逻辑相同,第一个判断是[0,-500),也就是由图像1移动到图像2的时候,瞬移到克隆1,然后从 克隆1到图像3

    9  自动播放功能

    • auto_play_timer = null会释放掉定时器,以求减少内存的占用

    我们让打开页面后自动播放,鼠标离开轮播图的时候自动播放,进入轮播图的时候停止播放

    你也可以不把自动播放函数提出来,而是使用element.click()进行模拟点击

    10  节流阀

    节流阀的作用是放置轮播图连续点击导致播放过快,方法是当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发

    • 这个节流阀可加可不加,如果不加也没什么问题

    我们如果想要动画结束后再执行某个函数,我们就要加入立即执行函数

    在这里可以这样写

    经测试效果一样

    之后对右侧按钮加入节流阀

    之后对左侧按钮加入节流阀

    这样在动画进行的过程中,再按按钮就没有用了

    11  源码

    html

    在html中可以加入新的轮播图

    1. html>
    2. <html lang="en">
    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>Documenttitle>
    8. <link rel="stylesheet" href="轮播图.css">
    9. <script src="animation.js">script>
    10. head>
    11. <body>
    12. <div class="rotate">
    13. <div class="content">
    14. <a href="#"><img src="upload/1.jpeg" alt="">a>
    15. <a href="#"><img src="upload/2.jpeg" alt="">a>
    16. <a href="#"><img src="upload/3.jpeg" alt="">a>
    17. <a href="#"><img src="upload/4.png" alt="">a>
    18. div>
    19. <div class="left">div>
    20. <div class="right">div>
    21. <ul class="bottom">
    22. ul>
    23. div>
    24. body>
    25. <script src="轮播图.js">script>
    26. html>

    css

    在css中可以改

    • .rotate width 轮播图区域宽度
    • .rotate height 轮播图区域高度
    • content width 轮播图图像大小,这里需要根据轮播图的数量变化而变化
    1. * {
    2. margin: 0px;
    3. padding: 0px;
    4. box-sizing: content-box;
    5. }
    6. li {
    7. list-style: none;
    8. }
    9. .rotate {
    10. position: relative;
    11. left:50%;
    12. transform: translate(-50%,0);
    13. width:500px;
    14. height:300px;
    15. overflow: hidden;
    16. }
    17. .content {
    18. position: absolute;
    19. width:500%; /*轮播图图片数量+1,比如你有四张图就用500%,3张图就用400%*/
    20. height:100%;
    21. display: flex;
    22. }
    23. .content a {
    24. cursor: default;
    25. width:100%;
    26. height:100%;
    27. }
    28. .content img {
    29. width:100%;
    30. height:100%;
    31. z-index: -1;
    32. }
    33. .left,.right {
    34. position:absolute;
    35. top:50%;
    36. transform: translate(0,-50%);
    37. width:23px;
    38. height:43px;
    39. display: none;
    40. cursor: pointer;
    41. }
    42. .left {
    43. left:0px;
    44. background-image:url(images/border_left.png);
    45. }
    46. .right {
    47. right:0px;
    48. background-image:url(images/border_right.png);
    49. }
    50. .bottom {
    51. position: absolute;
    52. bottom:0px;
    53. left:50%;
    54. transform: translate(-50%,0);
    55. display: flex;
    56. align-items: center;
    57. justify-content: space-around;
    58. width:100px;
    59. height:20px;
    60. }
    61. .bottom li {
    62. width:10px;
    63. height:10px;
    64. background-color:white;
    65. border-radius: 5px;
    66. cursor: pointer;
    67. }
    68. .bottom .current {
    69. background-color: skyblue;
    70. }

    JS

    在JS中可以改

    • img_width 轮播图区域大小
    • throttle 全部设置为true可以关闭节流阀
    1. left_btn = document.querySelector('.left')
    2. right_btn = document.querySelector('.right')
    3. rotate = document.querySelector('.rotate')
    4. content = document.querySelector('.content')
    5. bottom = document.querySelector('.bottom')
    6. // 左右按钮显示与隐藏,自动播放
    7. rotate.addEventListener('mouseenter',function() {
    8. left_btn.style.display = 'block';
    9. right_btn.style.display = 'block';
    10. clearInterval(auto_play_timer)
    11. auto_play_timer = null
    12. })
    13. rotate.addEventListener('mouseleave',function() {
    14. left_btn.style.display = 'none';
    15. right_btn.style.display = 'none';
    16. auto_play_timer = setInterval(function() {auto_play()},2000)
    17. })
    18. auto_play_timer = setInterval(function() {auto_play()},2000)
    19. // 动态生成索引li
    20. li_num = content.children.length
    21. for (i=0;i
    22. li = document.createElement('li')
    23. bottom.appendChild(li)
    24. }
    25. first_li = bottom.querySelector('li')
    26. first_li.className = 'current'
    27. // 添加最后一张图像
    28. new_first_img = content.firstElementChild.cloneNode(true)
    29. content.appendChild(new_first_img)
    30. // 确定当前是哪一个li
    31. img_width = 500
    32. all_lis = bottom.querySelectorAll('li')
    33. function which_li() {
    34. current_li_index = Math.round(-content.offsetLeft / img_width)
    35. if (current_li_index == li_num) {
    36. current_li_index = 0
    37. }
    38. if (current_li_index == -1) {
    39. current_li_index = 0
    40. }
    41. for (i=0;ilength;i++) {
    42. all_lis[i].className = ''
    43. }
    44. all_lis[current_li_index].className = 'current'
    45. }
    46. setInterval(which_li,15)
    47. // li的点击功能
    48. for (i=0;ilength;i++) {
    49. all_lis[i].distance = i * -img_width
    50. all_lis[i].addEventListener('click',function() {
    51. move_animation(content,this.distance)
    52. })
    53. }
    54. throttle = true
    55. // 右侧按钮切换
    56. new_create_img_position = -li_num * img_width //-1500
    57. last_img_position = -(li_num-1) * img_width //-1000
    58. function auto_play() {
    59. if (throttle) {
    60. throttle = false
    61. if (content.offsetLeft >= new_create_img_position && content.offsetLeft < last_img_position) {
    62. content.style.left = '0px'
    63. }
    64. current_li_index = current_li_index + 1
    65. if (current_li_index == li_num) {
    66. distance = new_create_img_position
    67. }
    68. else {
    69. distance = current_li_index * -img_width
    70. }
    71. move_animation(content,distance,function() {throttle = true})
    72. }
    73. }
    74. right_btn.addEventListener('click',function() {auto_play()})
    75. // 左侧按钮切换
    76. second_img_position = -img_width //-500
    77. left_btn.addEventListener('click',function() {
    78. if (throttle) {
    79. throttle = false
    80. if (content.offsetLeft > second_img_position && content.offsetLeft <= 0) {
    81. content.style.left = new_create_img_position + 'px'
    82. }
    83. current_li_index = current_li_index - 1
    84. if (current_li_index == -1) {
    85. distance = last_img_position
    86. }
    87. else {
    88. distance = current_li_index * -img_width
    89. }
    90. move_animation(content,distance,function() {throttle = true})
    91. }
    92. })
  • 相关阅读:
    springboot+vue【前后端分离】博客项目(已部署、大家可以来玩玩)
    CAN Ape 标定与诊断
    SpringBoot3学习笔记01
    LVGL---使用物理按键代替触摸(groups)
    MySQL8.0优化 - 锁 - 从数据操作的类型划分:读锁、写锁
    Vite2.0+Typescript+React+Antd+Less+Eslint+Prettier+Precommit构建标准化react应用
    【管理运筹学】第 9 章 | 网络计划(2,时间参数的计算 —— 工作的时间参数)
    SpringCloud Alibaba——分布式事务 Seata
    面试中的项目管理:如何展示你的组织能力
    智慧能源三维可视化平台实时动态呈现运维状态
  • 原文地址:https://blog.csdn.net/potato123232/article/details/126139377