当前位置:   article > 正文

JavaScript轮播图(面向对象)_轮播图-面向对象

轮播图-面向对象

步骤

轮播图1 HTML+CSS

轮播图2 动态生成页面

通过 JavaScript程序 生成 div标签中 所有 轮播图需要的标签

生成 ul ol div 标签节点

根据数组动态生成 原始 ul>li  ol>li

ul > li > img

ol > li

第一个li添加 class,active

将生成的 ul>li ol>li 字符串 写入 ul ol 标签节点

将 ul ol div 标签节点 写入 轮播图div中

获取 原始 ul>li ol>li 标签对象

克隆 第一个ul>li 和 最后一个 ul>li

将 克隆的第一个ul>li 写入 ul末位

将 克隆的最后一个ul>li 写入 ul起始

重新设定ul宽度

是 当前li个数 * li宽度

默认显示 原始轮播图的第一张 也就是 克隆写入之后的 第二个li

ul 默认 向左 定位 一个li宽度

轮播图3 自动轮播

通过 move() 运动函数 以动画效果完成ul标签定位的切换

自动轮播函数

定义一个全局变量 用于 存储 显示li标签的索引下标

初始值 是 1

通过 修改 变量中 的的数值 表示 显示的 li标签

也就是 通过 修改变量中存储的数值 控制 轮播图的执行

定义定时器

变量定义数值累加1

设定 焦点按钮的样式

设定 ul定位的数值

负的 当前显示的li标签 索引下标 * li宽度

通过 move() 运动函数 来 执行 ul标签定位的改变

move( ul标签 , { left : 负的index数值乘以li宽度 } , 运动结束触发的回调函数 )

焦点按钮设定函数

清除 所有的 ol>li 样式

给 显示的ul>li 对应的 ol>li 添加样式

如果 显示 当前ul>li的最后一个 给 第一个ol>li 添加样式

如果 是其他情况

给 显示的ul>li 索引下标 -1 对应的 ol>li 添加样式

ul切换运动终止的回调函数

如果 显示当前ul>li的最后一个

运动结束 给 index 赋值 1

也就是 要显示 当前ul>li的第二个

通过css样式设定 瞬间完成 ul定位的切换

ul标签对象.style.left = -index * li宽度 + 'px'

轮播图4 鼠标移入移出

给 轮播图div标签 添加事件

鼠标移入

终止轮播图的自动运行

也就是 清除  自动轮播 定时器

鼠标移出

再次执行轮播图的自动轮播

也就是 再次调用 autoLoop() 自动轮播函数

轮播图5 点击事件

给 一直存在的轮播图div添加点击事件

通过事件委托的语法形式 给标签添加点击事件

左右切换按钮

左切换按钮

显示上一次张

也就是 显示li标签索引下标 累减 1

根据 新的显示li标签的索引下标 定位ul标签

通过 move运动函数 运动完成 ul标签的定位切换

右切换按钮

显示下一次张

也就是 显示li标签索引下标 累加 1

根据 新的显示li标签的索引下标 定位ul标签

通过 move运动函数 运动完成 ul标签的定位切换

焦点按钮

显示 点击的 ol>li 对应的 ul>li 标签

也就是 ol>li 标签的索引下标 + 1

是 对应的 ul>li 标签的索引下标  

根据 新的显示li标签的索引下标 定位ul标签

通过 move运动函数 运动完成 ul标签的定位切换


 

轮播图6 防止点击过快

定义变量 存储默认值

触发点击事件 执行程序之前 先判断 变量储存的数据

如果是 原始值

变量赋值 其他数值 正常 执行之后的程序

如果是 其他数值

执行 return 终止 执行之后的程序

当 move() 运动函数执行结束 也就是 ul标签定位切换结束

给 变量 赋值 原始值true

可以执行下一次move()运动函数了

轮播图7 轮播图最小化隐藏

当 浏览器 最小化 / 隐藏 / 显示其他程序时

浏览器 会在 window操作系统 的 后台运行

浏览器 本身 不会触发执行任何程序

但是 浏览器中 JavaScript程序 会继续执行

也就是 autoLoop() 中的定时器 会自动继续执行

也就是 ul标签的定位 会被改变

解决方案:

浏览器最小化隐藏时

清除 定时器

浏览器显示时

再次 启动自动轮播函数

visibilitychange事件

添加个 document 的事件

浏览器显示状态监听事件

当浏览器显示状态改变时触发设定的函数程序

document.visibilityState

浏览器显示状态描述

hidden  

隐藏最小化状态

清除定时器

visible

显示状态

再次调用 自动轮播函数

代码(面向对象编程)

HTML部分:

  1. <!DOCTYPE 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. <link rel="stylesheet" href="./iconfont.ttf">
  8. <link rel="stylesheet" href="./iconfont.css">
  9. <title>Document</title>
  10. <style>
  11. *{
  12. padding: 0;
  13. margin: 0;
  14. }
  15. li{
  16. list-style: none;
  17. }
  18. a{
  19. text-decoration: none;
  20. }
  21. .banner{
  22. margin: auto;
  23. width: 1920px;
  24. height: 1030px;
  25. border: 2px solid red;
  26. position: relative;
  27. background-color: black;
  28. overflow: hidden;
  29. }
  30. .banner ul{
  31. width: 600%;
  32. height: 1030px;
  33. position: absolute;
  34. left: 0;
  35. top: 0;
  36. }
  37. .banner ul li{
  38. width: 1920px;
  39. height: 1030px;
  40. float: left;
  41. }
  42. .banner ol{
  43. width: 400px;
  44. height: 80px;
  45. position: absolute;
  46. bottom: 50px;
  47. left: 50%;
  48. transform: translateX(-50%);
  49. background-color: rgb(0, 0, 0,0.4);
  50. border-radius: 30px;
  51. display: flex;
  52. justify-content: space-around;
  53. align-items: center;
  54. cursor: pointer;
  55. }
  56. .banner ol li{
  57. width: 30px;
  58. height: 30px;
  59. margin: 20px;
  60. border-radius: 50%;
  61. background-color: white;
  62. }
  63. .banner div {
  64. padding: 0 30px;
  65. box-sizing: border-box;
  66. width: 100%;
  67. height: 80px;
  68. position: absolute;
  69. left: 0;
  70. top: 50%;
  71. transform: translateY(-100%);
  72. display: flex;
  73. justify-content: space-between;
  74. align-items: center;
  75. }
  76. .banner div a{
  77. font-size: 60px;
  78. color: white;
  79. }
  80. .banner ol .active{
  81. width: 45px;
  82. height: 45px;
  83. transition: 1s;
  84. background-color: red;
  85. }
  86. .banner div span{
  87. background-color: rgb(14, 13, 13,0.6);
  88. border-radius: 30%;
  89. box-sizing: border-box;
  90. display: block;
  91. padding: 20px 20px;
  92. transition: all 0.5s;
  93. }
  94. .banner div span:hover{
  95. background-color: red;
  96. font-size: 70px;
  97. }
  98. </style>
  99. </head>
  100. <body>
  101. <div class="banner"></div>
  102. <script src="./move.js"></script>
  103. <script src="./ind.js"></script>
  104. <script>
  105. //定义数组模拟后端传参
  106. const arr = [{url:'./image/1.png'},
  107. {url:'./image/2.png'},
  108. {url:'./image/6.png'},
  109. {url:'./image/4.png'},
  110. {url:'./image/5.png'}];
  111. const oBanner = document.querySelector(".banner");
  112. const obj = new CreateTabObj( oBanner , arr );
  113. // 入口函数调用
  114. obj.init();
  115. </script>
  116. </body>
  117. </html>

JavaScript部分

  1. class CreateTabObj {
  2. constructor(elment, msgArr) {
  3. // 获取标签对象
  4. this.ele = elment;
  5. // 数组模拟数据库
  6. this.arr = msgArr;
  7. //创建ul ol div节点
  8. this.oUl;
  9. this.oOl;
  10. this.oDiv;
  11. this.liWidth;
  12. this.ulLis;
  13. this.olLis;
  14. this.time;
  15. this.index = 1;
  16. this.res = true;
  17. }
  18. // 入口函数
  19. // 在一个函数中调用所有需要执行的函数程序
  20. // 也就是 只要 调用一个函数 就调用了所有需要调用的函数
  21. // 入口函数 必须定义名称是 init
  22. init() {
  23. this.theTag();
  24. this.slideshow();
  25. this.theMouseMoves();
  26. this.theMouseClick();
  27. this.hide();
  28. }
  29. // 动态生成标签内容函数
  30. theTag() {
  31. //创建ul ol div节点
  32. this.oUl = document.createElement('ul');
  33. this.oOl = document.createElement('ol');
  34. this.oDiv = document.createElement('div');
  35. // 设定节点内容
  36. this.oDiv.innerHTML = '<a href="JavaScript:;"><span name="left" class="iconfont icon-zuofanye"></span></a><a href="JavaScript:;"><span name="right" class="iconfont icon-youfanye"></span></a>'
  37. //循环遍历数组动态写入内容
  38. let oUlstr = '';
  39. let oOlstr = '';
  40. this.arr.forEach(function (item, key) {
  41. // item 是 数组单元的数据数值 也就是 存储图片数据的对象
  42. // 动态生成 ul>li
  43. oUlstr += `<li><img src="${item.url}"></li>`;
  44. // 动态生生 ol>li
  45. // 给 第一个li标签 添加class,active 也就是 背景颜色是红色
  46. // 给 每个li标签 添加 num属性属性值是索引下标
  47. oOlstr += key === 0 ? `<li name = "ollis" class = "active" num = ${key}></li>` : `<li name = "ollis" num = ${key}></li>`
  48. })
  49. // 将 生成的字符串 写入 标签节点中
  50. this.oUl.innerHTML = oUlstr;
  51. this.oOl.innerHTML = oOlstr;
  52. // 添加节点,添加到div中
  53. this.ele.appendChild(this.oUl);
  54. this.ele.appendChild(this.oOl);
  55. this.ele.appendChild(this.oDiv);
  56. //获取生成的 原始 ul>li ol>li标签对象
  57. this.ulLis = this.oUl.querySelectorAll('li');
  58. this.olLis = this.oOl.querySelectorAll('li');
  59. //获取标签宽度
  60. this.liWidth = this.ulLis[0].offsetWidth;
  61. // 克隆标签
  62. let ulLisFirst = this.ulLis[0].cloneNode(true);
  63. let ulLisLast = this.ulLis[this.ulLis.length - 1].cloneNode(true);
  64. // 将 克隆的第一个 写入 ul的最后
  65. this.oUl.appendChild(ulLisFirst)
  66. // 将 克隆的最后一个 写入 ul的起始
  67. this.oUl.insertBefore(ulLisLast, this.ulLis[0]);
  68. // 重新设定ul宽度
  69. // 克隆之后li标签个数 * li标签宽度
  70. // 克隆之后li标签个数是数组单元个数+2
  71. this.oUl.style.width = (this.arr.length + 2) * this.liWidth + 'px';
  72. // 将ul向左定位一个li的宽度
  73. this.oUl.style.left = -this.liWidth + 'px';
  74. }
  75. //自动轮播函数
  76. slideshow() {
  77. // 设定定时器
  78. this.time = setInterval(() => {
  79. if (this.res) {
  80. this.res = false;
  81. } else {
  82. return;
  83. }
  84. // 变量累加1
  85. this.index++;
  86. // index变量累加后 设定 对应的焦点样式
  87. this.point();
  88. // 通过 move() 运动函数 完成 ul标签 定位的切换
  89. // 回调函数使用 bind() 方法 修改this指向
  90. // 当前 this 指向实例化对象 修改回调函数的this指向是当前this也就是实例化对象
  91. move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this))
  92. }, 2000)
  93. }
  94. //move运动函数执行结束触发的回调函数
  95. circulation() {
  96. // 如果是 当前ul的最后一个li 运动结束 立即切换到 当前ul的第二个li
  97. // 也就是 index 是 最后一个li的索引下标 也就是 arr.length+2-1
  98. // 切换到 当前ul的第二个li 也就是 index 赋值 1
  99. if (this.index === this.arr.length + 2 - 1) {
  100. this.index = 1;
  101. // 如果是 当前ul的第一个li 运动结束 立即切换到 当前ul的倒数二个li
  102. // 也就是 index 是 第一个li的索引下标 也就是 0
  103. // 切换到 当前ul的倒数第二个li 也就是 index 赋值 arr.length+2-1-1
  104. } else if (this.index === 0) {
  105. // 给 变量 赋值 当前ul的倒数第二个li的索引下标
  106. this.index = this.arr.length + 2 - 2
  107. }
  108. // 给 ul 执行定位 瞬间切换
  109. // 根据新的index数值 给 ul标签 做瞬间定位切换
  110. this.oUl.style.left = -this.index * this.liWidth + 'px';
  111. // 运动结束 也就是 一次ul切换完成
  112. // 给变量赋值原始值 可以 执行下一次运动
  113. this.res = true;
  114. }
  115. //焦点图函数
  116. point() {
  117. // 清除所有的ol>li焦点样式
  118. this.olLis.forEach((item) => {
  119. item.classList.remove('active');
  120. })
  121. // 如果 显示 当前ul中最后一个li 给 ol>li 中的 第一个添加样式
  122. if (this.index === this.arr.length + 2 - 1) {
  123. // 给 索引是0 的 第一个 ol>li 添加 css样式
  124. this.olLis[0].classList.add('active');
  125. // 如果 显示 点券ul中第一个li 给 ol>li 中的 最后一个添加样式
  126. } else if (this.index === 0) {
  127. // 给 ol>li 的最后一个 添加 css样式
  128. this.olLis[this.olLis.length - 1].classList.add('active');
  129. // 其他情况 给 当期ul>li索引下标 -1 对应的 ol>li 添加样式
  130. } else {
  131. // 当前 显示的ul>li的索引下标 也就是 index
  132. // 数值 -1 是 对应的 ol>li 的 索引下标
  133. this.olLis[this.index - 1].classList.add("active");
  134. }
  135. }
  136. //鼠标移入移出函数
  137. theMouseMoves() {
  138. // 鼠标移入
  139. this.ele.addEventListener('mouseenter', () => {
  140. // 清除定时器
  141. clearInterval(this.time);
  142. })
  143. // 鼠标移出
  144. this.ele.addEventListener('mouseleave', () => {
  145. // 再次调用自动轮播
  146. this.slideshow();
  147. })
  148. }
  149. //点击事件函数
  150. theMouseClick() {
  151. // 给 轮播图div添加点击事件
  152. this.ele.addEventListener('click', (e) => {
  153. // 判断 如果 事件对象 e.target 的name属性值是 left 点击的是左切换按钮
  154. if (e.target.getAttribute('name') === "left") {
  155. // 防止点击过快
  156. if (this.res) {
  157. this.res = false;
  158. } else {
  159. return;
  160. }
  161. // 切换显示上一个li
  162. // 也就是 索引下标 累减 1
  163. this.index--;
  164. // 调用函数 重新设定 焦点按钮css样式
  165. this.point();
  166. // 根据新的索引下标 通过move()运动函数
  167. // 动画效果 完成ul标签的重新定位
  168. move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));
  169. } else if (e.target.getAttribute('name') === "right") {
  170. // 判断 如果 事件对象 e.target 的name属性值是 right 点击的是左切换按钮
  171. if (this.res) {
  172. this.res = false;
  173. } else {
  174. return;
  175. }
  176. this.index++;
  177. this.point();
  178. move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));
  179. } else if (e.target.getAttribute('name') === "ollis") {
  180. // 判断 如果 事件对象 e.target 的name属性值是 olLi 点击的是焦点按钮
  181. if (this.res) {
  182. this.res = false;
  183. } else {
  184. return;
  185. }
  186. // 获取当前 点击的ol>li标签 num属性的属性值
  187. // 也就是 点击的ol>li标签的 索引下标
  188. // num属性值+1 是 对应的 ul>li 的索引下标
  189. // num属性值 是 字符串类型 必须要转化为数值类型 再 执行+1 运算
  190. this.index = Number(e.target.getAttribute('num')) + 1;
  191. this.point();
  192. move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));
  193. }
  194. })
  195. }
  196. // 浏览器最小化隐藏
  197. hide() {
  198. // 给 document 添加 浏览器显示状态监听
  199. document.addEventListener('visibilitychange', () => {
  200. // 如果 浏览器显示状态描述 是 hidden
  201. if (document.visibilityState === 'hidden') {
  202. // 证明当前浏览器隐藏最小化
  203. // 清除定时器
  204. clearInterval(this.time);
  205. // 如果 浏览器显示状态描述 是 visible
  206. } else if (document.visibilityState === 'visible') {
  207. // 证明当前浏览器 显示
  208. // 再次调用 自动轮播函数
  209. this.autoLoop();
  210. }
  211. })
  212. }
  213. }

运行结果 

 

总结

控制轮播图的核心

就是 控制 变量中的存储的数值

也就是 控制 显示 li标签的索引下标

通过 设定 ul标签的定位 是 变量 * li宽度

也就是 设定 ul标签的定位 显示 变量对应索引下标对应的li标签

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/945081
推荐阅读
相关标签
  

闽ICP备14008679号