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部分:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="./iconfont.ttf"><link rel="stylesheet" href="./iconfont.css"><title>Document</title><style>*{padding: 0;margin: 0;}li{list-style: none;}a{text-decoration: none;}.banner{margin: auto;width: 1920px;height: 1030px;border: 2px solid red;position: relative;background-color: black;overflow: hidden;}.banner ul{width: 600%;height: 1030px;position: absolute;left: 0;top: 0;}.banner ul li{width: 1920px;height: 1030px;float: left;}.banner ol{width: 400px;height: 80px;position: absolute;bottom: 50px;left: 50%;transform: translateX(-50%);background-color: rgb(0, 0, 0,0.4);border-radius: 30px;display: flex;justify-content: space-around;align-items: center;cursor: pointer;}.banner ol li{width: 30px;height: 30px;margin: 20px;border-radius: 50%;background-color: white;}.banner div {padding: 0 30px;box-sizing: border-box;width: 100%;height: 80px;position: absolute;left: 0;top: 50%;transform: translateY(-100%);display: flex;justify-content: space-between;align-items: center;}.banner div a{font-size: 60px;color: white;}.banner ol .active{width: 45px;height: 45px;transition: 1s;background-color: red;}.banner div span{background-color: rgb(14, 13, 13,0.6);border-radius: 30%;box-sizing: border-box;display: block;padding: 20px 20px;transition: all 0.5s;}.banner div span:hover{background-color: red;font-size: 70px;}</style>
</head>
<body><div class="banner"></div><script src="./move.js"></script><script src="./ind.js"></script><script>//定义数组模拟后端传参const arr = [{url:'./image/1.png'},{url:'./image/2.png'},{url:'./image/6.png'},{url:'./image/4.png'},{url:'./image/5.png'}];const oBanner = document.querySelector(".banner");const obj = new CreateTabObj( oBanner , arr );// 入口函数调用obj.init();</script>
</body>
</html>
JavaScript部分
class CreateTabObj {constructor(elment, msgArr) {// 获取标签对象this.ele = elment;// 数组模拟数据库this.arr = msgArr;//创建ul ol div节点this.oUl;this.oOl;this.oDiv;this.liWidth;this.ulLis;this.olLis;this.time;this.index = 1;this.res = true;}// 入口函数// 在一个函数中调用所有需要执行的函数程序// 也就是 只要 调用一个函数 就调用了所有需要调用的函数// 入口函数 必须定义名称是 initinit() {this.theTag();this.slideshow();this.theMouseMoves();this.theMouseClick();this.hide();}// 动态生成标签内容函数theTag() {//创建ul ol div节点this.oUl = document.createElement('ul');this.oOl = document.createElement('ol');this.oDiv = document.createElement('div');// 设定节点内容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>'//循环遍历数组动态写入内容let oUlstr = '';let oOlstr = '';this.arr.forEach(function (item, key) {// item 是 数组单元的数据数值 也就是 存储图片数据的对象// 动态生成 ul>lioUlstr += `<li><img src="${item.url}"></li>`;// 动态生生 ol>li// 给 第一个li标签 添加class,active 也就是 背景颜色是红色// 给 每个li标签 添加 num属性属性值是索引下标oOlstr += key === 0 ? `<li name = "ollis" class = "active" num = ${key}></li>` : `<li name = "ollis" num = ${key}></li>`})// 将 生成的字符串 写入 标签节点中this.oUl.innerHTML = oUlstr;this.oOl.innerHTML = oOlstr;// 添加节点,添加到div中this.ele.appendChild(this.oUl);this.ele.appendChild(this.oOl);this.ele.appendChild(this.oDiv);//获取生成的 原始 ul>li ol>li标签对象this.ulLis = this.oUl.querySelectorAll('li');this.olLis = this.oOl.querySelectorAll('li');//获取标签宽度this.liWidth = this.ulLis[0].offsetWidth;// 克隆标签let ulLisFirst = this.ulLis[0].cloneNode(true);let ulLisLast = this.ulLis[this.ulLis.length - 1].cloneNode(true);// 将 克隆的第一个 写入 ul的最后 this.oUl.appendChild(ulLisFirst)// 将 克隆的最后一个 写入 ul的起始 this.oUl.insertBefore(ulLisLast, this.ulLis[0]);// 重新设定ul宽度 // 克隆之后li标签个数 * li标签宽度// 克隆之后li标签个数是数组单元个数+2this.oUl.style.width = (this.arr.length + 2) * this.liWidth + 'px';// 将ul向左定位一个li的宽度this.oUl.style.left = -this.liWidth + 'px';}//自动轮播函数slideshow() {// 设定定时器this.time = setInterval(() => {if (this.res) {this.res = false;} else {return;}// 变量累加1this.index++;// index变量累加后 设定 对应的焦点样式this.point();// 通过 move() 运动函数 完成 ul标签 定位的切换// 回调函数使用 bind() 方法 修改this指向 // 当前 this 指向实例化对象 修改回调函数的this指向是当前this也就是实例化对象move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this))}, 2000)}//move运动函数执行结束触发的回调函数circulation() {// 如果是 当前ul的最后一个li 运动结束 立即切换到 当前ul的第二个li// 也就是 index 是 最后一个li的索引下标 也就是 arr.length+2-1 // 切换到 当前ul的第二个li 也就是 index 赋值 1 if (this.index === this.arr.length + 2 - 1) {this.index = 1;// 如果是 当前ul的第一个li 运动结束 立即切换到 当前ul的倒数二个li// 也就是 index 是 第一个li的索引下标 也就是 0// 切换到 当前ul的倒数第二个li 也就是 index 赋值 arr.length+2-1-1} else if (this.index === 0) {// 给 变量 赋值 当前ul的倒数第二个li的索引下标this.index = this.arr.length + 2 - 2}// 给 ul 执行定位 瞬间切换// 根据新的index数值 给 ul标签 做瞬间定位切换this.oUl.style.left = -this.index * this.liWidth + 'px';// 运动结束 也就是 一次ul切换完成// 给变量赋值原始值 可以 执行下一次运动this.res = true;}//焦点图函数point() {// 清除所有的ol>li焦点样式this.olLis.forEach((item) => {item.classList.remove('active');})// 如果 显示 当前ul中最后一个li 给 ol>li 中的 第一个添加样式if (this.index === this.arr.length + 2 - 1) {// 给 索引是0 的 第一个 ol>li 添加 css样式this.olLis[0].classList.add('active');// 如果 显示 点券ul中第一个li 给 ol>li 中的 最后一个添加样式} else if (this.index === 0) {// 给 ol>li 的最后一个 添加 css样式this.olLis[this.olLis.length - 1].classList.add('active');// 其他情况 给 当期ul>li索引下标 -1 对应的 ol>li 添加样式} else {// 当前 显示的ul>li的索引下标 也就是 index// 数值 -1 是 对应的 ol>li 的 索引下标 this.olLis[this.index - 1].classList.add("active");}}//鼠标移入移出函数theMouseMoves() {// 鼠标移入this.ele.addEventListener('mouseenter', () => {// 清除定时器clearInterval(this.time);})// 鼠标移出this.ele.addEventListener('mouseleave', () => {// 再次调用自动轮播this.slideshow();})}//点击事件函数theMouseClick() {// 给 轮播图div添加点击事件this.ele.addEventListener('click', (e) => {// 判断 如果 事件对象 e.target 的name属性值是 left 点击的是左切换按钮if (e.target.getAttribute('name') === "left") {// 防止点击过快if (this.res) {this.res = false;} else {return;}// 切换显示上一个li // 也就是 索引下标 累减 1 this.index--;// 调用函数 重新设定 焦点按钮css样式this.point();// 根据新的索引下标 通过move()运动函数 // 动画效果 完成ul标签的重新定位move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));} else if (e.target.getAttribute('name') === "right") {// 判断 如果 事件对象 e.target 的name属性值是 right 点击的是左切换按钮if (this.res) {this.res = false;} else {return;}this.index++;this.point();move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));} else if (e.target.getAttribute('name') === "ollis") {// 判断 如果 事件对象 e.target 的name属性值是 olLi 点击的是焦点按钮if (this.res) {this.res = false;} else {return;}// 获取当前 点击的ol>li标签 num属性的属性值 // 也就是 点击的ol>li标签的 索引下标 // num属性值+1 是 对应的 ul>li 的索引下标// num属性值 是 字符串类型 必须要转化为数值类型 再 执行+1 运算this.index = Number(e.target.getAttribute('num')) + 1;this.point();move(this.oUl, { left: -this.index * this.liWidth }, this.circulation.bind(this));}})}// 浏览器最小化隐藏hide() {// 给 document 添加 浏览器显示状态监听document.addEventListener('visibilitychange', () => {// 如果 浏览器显示状态描述 是 hidden if (document.visibilityState === 'hidden') {// 证明当前浏览器隐藏最小化// 清除定时器clearInterval(this.time);// 如果 浏览器显示状态描述 是 visible } else if (document.visibilityState === 'visible') {// 证明当前浏览器 显示// 再次调用 自动轮播函数this.autoLoop();}})}
}
运行结果
总结
控制轮播图的核心
就是 控制 变量中的存储的数值
也就是 控制 显示 li标签的索引下标
通过 设定 ul标签的定位 是 变量 * li宽度
也就是 设定 ul标签的定位 显示 变量对应索引下标对应的li标签
JavaScript轮播图(面向对象)相关推荐
- JavaScript轮播图代码
JavaScript轮播图代码 <html><head><meta charset="utf-8"><title>轮播图</t ...
- 原生JavaScript轮播图效果实现
原生JavaScript实现轮播图切换效果的实现过程 本文所用代码仅供个人学习.此部分代码系按原腾讯电脑管家首页的轮播图效果,采用原生JS技术予以实现(原网页采用jQurey等技术). 1. 文件准备 ...
- 阶段二 网页搭建入门之javaScript与前端案例 javaScript轮播图
加粗样式## 效果图 图片素材 html <!doctype html> <html lang="en"> <head><meta cha ...
- 【学习笔记63】轮播图 —— 面向对象
目录 一.案例效果 二.轮播图的分析 (一)面向对象书写的小技巧 (二)面向过程 (三)面向对象 三.HTML和CSS代码 四.JS代码分析 (一)ES6 class类的使用 (二) 添加焦点 (三) ...
- js原生 JavaScript轮播图【渐变淡入淡出】效果实现(附代码)
目录 前言 轮播图的组成以及实现思想 左右按钮的隐藏与显示 核心思想 代码实现 动态生成底部小圆圈 核心思想 代码实现 右左按钮实现 核心思想 代码实现 实现自动播放 核心思想 代码实现 整体代码(复 ...
- JavaScript 轮播图案例
前言 一名刚刚入坑前端的小白,如有错误还望指出,谢谢您的查阅 提示:以下是本篇文章正文内容,下面案例可供参考 轮播图案例(仅供参考) <!DOCTYPE html> <html la ...
- javascript轮播图(缓冲运动)
哈喽,大家好呀!我又来咯!相信大家在翻网页的时候都会看到首页的轮播图!今天讲讲实现原理,感觉有用就收藏吧! 轮播图主要是利用缓冲运动来实现图片的切换,这样看起来比较有画面感哈! 那么什么叫做缓冲运动呢 ...
- html 轮播图自适应,JavaScript 自适应轮播图
JavaScript 自适应轮播图 代码 话不多说,先上代码,方便复制粘贴.演示 轮播图 *{ margin: 0; padding: 0; } ul{ list-style: none; } img ...
- HTML+CSS+JavaScript实现轮播图效果
前言 先奉上本文需要的所有资源,免费下载,代码有详细注释,可搭配本文使用: 前端JavaScript实现轮播图效果 百度网盘:百度网盘 请输入提取码 提取码:slbt 没有添加动画效果,添加了自动切换 ...
最新文章
- 2022入坑图像分割,我该从哪儿入手?
- Hbuilder开发移动App(1)
- 【干货】救火必备:线上故障排查套路大全
- 北京大学 微软:预训练模型(Transformer)中的知识神经元
- 《数据库SQL实战》从titles表获取按照title进行分组
- DDL 创建与查询数据库
- 华为谈“不造车” ,每辆车上赚1万元。王兴:特斯拉终于遇到真正的对手!...
- iis5.1安装方法(适用于XP)以及运行调试asp程序,创建虚拟目录【整理】
- Java中try必须要结合catch吗_如何优雅的实现 try/catch 异常块?
- android调用本地js文件上传,原生JS实现前端本地文件上传
- 动态库静态库的链接过程
- dell服务器 指示灯_服务器指示灯说明
- 军事训练飞机的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- Java教务管理系统
- WSUS 3.0 SP2服务器配置
- c语言编程最大公约数穷举发,C语言基本算法 :1.求最大公约数与最小公倍数
- 编程求斐波那契数列的第n项和前n项之和。
- SOC设计之AMBA总线-AHB总线详解
- 钉钉的sonar集成通知 dingding-sonar
- 【菜鸡的自动化学习之旅】《电力电子技术》学习笔记1 ———— 电力电子器件