JS案例-网页轮播图
- 鼠标经过轮播图模块,左右按钮提示,离开隐藏左右按钮
- 点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理
- 图片播放的同时,下面小圆圈模块跟随一起变化
- 点击小圆圈,可以播放相应图片
- 鼠标不经过轮播图,轮播图也会自动播放图片
- 鼠标经过,轮播图模块自动播放停止
第一步 鼠标经过显示按钮 鼠标离开按钮消失
//获取元素
var arrow_l = document.querySelector('.arrow-l');
var arrow_r = document.querySelector('.arrow-r');
var focus = document.querySelector('.focus');
//鼠标经过显示按钮
focus.addEventListener('mouseenter', function () {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
})
focus.addEventListener('mouseleave', function () {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
})
第二步:考虑如何动态生成小圆圈 让小圆圈个数与图片个数一致
首先得到ul里图片个数,利用循环动态生成小圆圈,创建节点并插入节点,然后给第一个小圆圈插入current类
//动态生成小圆圈
var ul = focus.querySelector('ul');//必须限定focus里面的
var ol = focus.querySelector('.circle');
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
ol.appendChild(li);
//[]
}
ol.children[0].className = 'current';//第一个小圆圈默认变色
第三步:利用排他思想,实现点击小圆圈变色
//可以直接在生成小圆圈的同时绑定点击事件
li.addEventListener('click', function () {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
this.className = 'current';
})
第四步:点击小圆圈滚动图片
注意是ul在移动
当点击某个小圆圈,就让图片滚动,移动距离为图片索引号*图片宽度
知识点:索引号如何得到?
- 通过给每个li设定自定义属性点击时获取自定义属性
var ul = focus.querySelector('ul');//必须限定focus里面的
var ol = focus.querySelector('.circle');
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
//通过自定义属性记录小圆圈索引号
li.setAttribute('index', i);
ol.appendChild(li);
//可以直接在生成小圆圈的同时绑定点击事件
li.addEventListener('click', function () {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
this.className = 'current';
//点击小圆圈移动图片
var index = this.getAttribute('index');
var focusWidth = focus.offsetWidth;
animate(ul, -index * focusWidth);
})
}
第五步:点击左右按钮滚动
思路:声明一个变量,每点击一次number++
但是当点击次数过多会走到空白区域
如何实现无缝滚动?
- 把ul第一个li复制一份,放到ul后面,当图片滚动到克隆的最后一张的时候不做动画直接快速跳回第一张:left=0,同时num=0;
如何克隆第一张图片?
- 利用节点的克隆和添加操作
ol.children[0].className = 'current';//第一个小圆圈默认变色
var firstLi = ul.children[0].cloneNode(true);
ul.appendChild(firstLi);//克隆第一张图
var num = 0;
arrow_r.addEventListener('click', function () {
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth);
})
第六步:点击按钮小圆圈跟随变化
再定义一个变量circle,每次点击一次按钮则++,如果circle==4,说明走到最后这张图片,使circle复原
var circle = 0;
arrow_r.addEventListener('click', function () {
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth);
//实现点击按钮小圆圈跟随变化
circle++;
if (circle == ol.children.length) {
circle = 0;
}
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
第七步:此时有两个bug
按钮的点击操作和圆点的点击是不同变量,无法共同使用,两个事件的变量需要同步
应该在点击小圆点事件中添加
num = index;
circle = index;
第八步:左侧按钮同理
arrow_l.addEventListener('click', function () {
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWidth);
//实现点击按钮小圆圈跟随变化
circle--;
if (circle < 0) {
circle = ol.children.length - 1;
}
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
})
第十步 代码优化 相同的可以封装函数
function circleChange() {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
}
三元表达式简化
circle = circle < 0 ? ol.children.length - 1 : circle;
// if (circle < 0) {
// circle = ol.children.length - 1;
// }
最后:自动播放!
发现自动播放时和点击右侧按钮很类似
可以手动调用右侧按钮点击事件arrow_r.click()
focus.addEventListener('mouseenter', function () {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
clearInterval(timer);//鼠标经过停止定时器
timer = none;
})
focus.addEventListener('mouseleave', function () {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
timer = setInterval(function () {//鼠标离开开启定时器
arrow_r.click();//手动调用点击事件
}, 2000)
})
补充:节流阀
防止轮播图按钮连续点击造成播放过快
目的:当上一个函数动画执行完毕,再去执行下一个函数动画,让事件无法连续触发
利用回调函数,添加一个变量来控制,锁住函数和解锁函数
- 开始设置一个变量var flag=true
- if(flag) {flag=false;do something}关闭水龙头
利用回调函数 动画执行完毕(使用回调函数),false=true 打开水龙头
完整js代码
window.addEventListener('load', function () {
//获取元素
var arrow_l = document.querySelector('.arrow-l');
var arrow_r = document.querySelector('.arrow-r');
var focus = document.querySelector('.focus');
var focusWidth = focus.offsetWidth;
var num = 0;
//鼠标经过显示按钮
focus.addEventListener('mouseenter', function () {
arrow_l.style.display = 'block';
arrow_r.style.display = 'block';
clearInterval(timer);//鼠标经过停止定时器
timer = none;
})
focus.addEventListener('mouseleave', function () {
arrow_l.style.display = 'none';
arrow_r.style.display = 'none';
timer = setInterval(function () {//鼠标离开开启定时器
arrow_r.click();//手动调用点击事件
}, 2000)
})
//动态生成小圆圈
var ul = focus.querySelector('ul');//必须限定focus里面的
var ol = focus.querySelector('.circle');
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
//通过自定义属性记录小圆圈索引号
li.setAttribute('index', i);
ol.appendChild(li);
//可以直接在生成小圆圈的同时绑定点击事件
li.addEventListener('click', function () {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
this.className = 'current';
//点击小圆圈移动图片
var index = this.getAttribute('index');
//当我们点击了某个li,就要把这个li的索引号给num//////////////////////////////bug必须改
num = index;
circle = index;
animate(ul, -index * focusWidth);
})
}
ol.children[0].className = 'current';//第一个小圆圈默认变色
var firstLi = ul.children[0].cloneNode(true);
ul.appendChild(firstLi);//克隆第一张图
var circle = 0;//全局变量
var flag = true;
arrow_r.addEventListener('click', function () {
if (flag) {
flag = false;//关闭节流阀
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
animate(ul, -num * focusWidth, function () {
flag = true;//打开节流阀
});
//实现点击按钮小圆圈跟随变化
circle++;
if (circle == ol.children.length) {
circle = 0;
}
circleChange();
}
})
arrow_l.addEventListener('click', function () {
if (flag) {
flag = false;
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * focusWidth + 'px';
}
num--;
animate(ul, -num * focusWidth, function () {
flag = true;
});
//实现点击按钮小圆圈跟随变化
circle--;
circle = circle < 0 ? ol.children.length - 1 : circle;
// if (circle < 0) {
// circle = ol.children.length - 1;
// }
circleChange();
}
})
function circleChange() {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
}
var timer = setInterval(function () {
arrow_r.click();//手动调用点击事件
}, 2000)
})
animate.js
function animate(obj, target, callback) {
// console.log(callback); callback = function() {} 调用的时候 callback()
// 先清除以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function () {
// 步长值写到定时器的里面
// 把我们步长值改为整数 不要出现小数的问题
// var step = Math.ceil((target - obj.offsetLeft) / 10);
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
// 停止动画 本质是停止定时器
clearInterval(obj.timer);
// 回调函数写到定时器结束里面
// if (callback) {
// // 调用函数
// callback();
// }
callback && callback();//借助短路运算如果有参数传入才会调用callback
}
// 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
相关html
<div class="focus">
<a href="javascript:;" class="arrow-l"><</a>
<a href="javascript:;" class="arrow-r">></a>
<ul>
<li><a href="#"><img src="upload/focus1.png" alt=""></a></li>
<li><a href="#"><img src="upload/focus1.jpg" alt=""></a></li>
<li><a href="#"><img src="upload/focus2.jpg" alt=""></a></li>
<li><a href="#"><img src="upload/focus3.jpg" alt=""></a></li>
</ul>
<ol class="circle">
</ol>
相关css
.focus {
float: left;
overflow: hidden;
position: relative;
width: 721px;
height: 455px;
}
.arrow-l,.arrow-r {
display: none;
position: absolute;
top: 50%;
margin-top: -20px;
width: 24px;
height: 40px;
color:rgb(175, 170, 170);
font-size: 20px;
line-height: 40px;
text-align: center;
z-index: 10;
background:rgba(0,0,0, .5);
}
.arrow-l {
left: 0;
border-radius: 0 30px 30px 0;
}
.arrow-r {
right: 0;
border-radius: 30px 0 0 30px;
}
.focus ul{
position: absolute;
top: 0;
left: 0;
width: 600%;
}
.focus ul li{
float: left;
}
.circle{
position: absolute;
bottom: 0;
left: 40px;
bottom: 0;
height: 18px;
width: 150px;
}
.circle li{
height: 12px;
width: 12px;
float: left;
border-radius: 8px;
border: 1px solid #e4e4e4;
margin: 0 4px;
}
.current {
background-color: #e4e4e4;
}
JS案例-网页轮播图的更多相关文章
- 原生JS实现简易轮播图
原生JS实现简易轮播图(渐变?) 最近做网页总是会用到轮播图,我就把之前写的轮播图单独拿出来吧,如果有...如果真的有人也需要也可以复制去用用啊..哈~.. window.onload = funct ...
- jQuery与原生js实现banner轮播图
jQuery与原生js实现banner轮播图: (jq需自己加载)(图片需自己加载) <!DOCTYPE html> <html> <head> <meta ...
- JS+css3焦点轮播图PC端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js原生实现轮播图效果(面向对象编程)
面向对象编程js原生实现轮播图效果 1.先看效果图 2.需要实现的功能: 自动轮播 点击左右箭头按钮无缝轮播 点击数字按钮切换图片 分析:如何实现无缝轮播? 在一个固定大小的相框里有一个ul标签,其长 ...
- js - 面向对象 - 小案例:轮播图、随机点名、选项卡、鼠标拖拽
面向对象 对象 : (黑盒子)不了解内部结构, 知道表面的各种操作. 面向对象 : 不了解原理的情况下 会使用功能 . 面向对象是一种通用思想,并非编程中能用,任何事情都能用. 编程语言的面向对象的特 ...
- JS学习笔记--轮播图效果
希望通过自己的学习收获哪怕收获一点点,进步一点点都是值得的,加油吧!!! 本章知识点:index this for if else 下边我分享下通过老师教的方式写的轮播图,基础知识实现: 1.css代 ...
- 原生 js 左右切换轮播图
使用方法: 可能很多人对轮播图感兴趣,下面奉上本人的 原生 js 轮播代码复制 js 到页面的最底部,样式在 css 里改,js 基本不用动,有什么不懂的可以 加本人 QQ172360937 咨询 或 ...
- photoSlider-原生js移动开发轮播图、相册滑动插件
详细内容请点击 在线预览 立即下载 使用方法: 分别引用css文件和js文件 如: <link rel="stylesheet" type="text/css& ...
- photoSlider-html5原生js移动开发轮播图-相册滑动插件
简单的移动端图片滑动切换浏览插件 分别引用css文件和js文件 如: <link rel="stylesheet" type="text/css" hre ...
- 用 JS 写 (轮播图 / 选项卡 / 滑动门)
页面中经常会用到各式各样的轮播图,今天贺贺为大家介绍一种常用的方法,对于JS我们需要举一反三,一种方法可以对多个轮播样式进行渲染. <head> <meta charset=&quo ...
随机推荐
- SqlSugar的查询函数SqlFunc
用法 我们可以使用SqlFunc这个类调用Sql函数,用法如下: db.Queryable<Student>().Where(it => SqlFunc.ToLower(it.Nam ...
- C/C++ 原生套接字抓取FTP数据包
网络通信在今天的信息时代中扮演着至关重要的角色,而对网络数据包进行捕获与分析则是网络管理.网络安全等领域中不可或缺的一项技术.本文将深入介绍基于原始套接字的网络数据包捕获与分析工具,通过实时监控网络流 ...
- npm查看插件所有版本命令
npm view webpack versions npm view webpack versions
- Windows 恶意软件数量是 Mac 的 5000 倍,是 Linux 的 36 倍
AV-TEST 是一个独立的测试机构,他们会根据各种标准对操作系统的防病毒和安全软件进行评估和评级,并将测试结果免费提供给用户,帮助用户选择最适合自己的产品.近日,AV-TEST 联合旗下的威胁情报平 ...
- CentOS7下的防火墙配置整理
CentOS7下的防火墙配置整理 一.firewalld的基本使用 [root@localhost jack]# systemctl start firewalld # 启动防火墙 [root@loc ...
- (C语言)每日代码||2023.12.24||printf换行的三种方法
#include <stdio.h> int main() { //printf()函数不同参数间可以换行 printf("num one : %d,num two : %d&q ...
- docker容器-乌班图安装vim
apt-get update && apt-get install -y vim
- [JVM] Java内存分配
Java内存分配 程序计数器 程序计数器是一块较小的内存区域,作用可以看做是当前线程执行的字节码的位置指示器.分支.循环.跳转.异常处理和线程恢复等基础功能都需要依赖这个计算器来完成. 虚拟机栈 虚拟 ...
- ABC 311
前四题过水 E 枚举正方形的上边界所在行.对于第 \(i\) 行一个没洞的位置 \((i,j)\),我们尝试求出以它为右上角的无洞正方形个数. 结论:设以 \((i,j-1)\) 为右上角的无洞正方形 ...
- 吉特日化MES & 某配料自动化项目业务架构图
作者:情缘 出处:http://www.cnblogs.com/qingyuan/ 关于作者:从事仓库,生产软件方面的开发,在项目管理以及企业经营方面寻求发展之路 版权声明:本文版权归作者和博客园 ...