JavaScript学习笔记—制作网页轮播图

JavaScript学习笔记—制作网页轮播图

一、 分析:

构成模块:

  • 最外边一个大的div
  • 里头一个ul ul里每个小li放一张图片 (核心的滚动区域)
  • 左右两个按钮
  • 小圆点

功能需求:

  1. 鼠标经过轮播图模块,显示左右按钮,离开隐藏左右按钮。
  2. 动态生成小圆圈 有几张图片,我们就生成几个小圆圈
  3. 当前的小li 设置current 类名 (排他思想)
  4. 点击小圆圈滚动图片,播放相应图片
  5. 点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理
  6. 图片播放的同时,下面小圆圈模块跟随一起变化。
  7. 鼠标不经过轮播图时,轮播图会自动播放图片。
  8. 鼠标经过,轮播图模块,自动播放停止。

二、 分步实现代码

step 1:
// 1.获取元素
 var arrow_r=document.querySelector('.arrow-r');
 var arrow_l=document.querySelector('.arrow-l');
 var focus =document.querySelector('.focus');
 // 2.鼠标经过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 ';
 });
step 2:动态生成小圆圈
分析:
  1. 核心思想:小圆圈的个数要跟图片张数一致
  2. 所以,首先先得到 ul 里面图片的张数(图片放入li里面,所以就是li的个数)
  3. 利用循环动态生成小圆圈(这个小圆圈要放入ol里面)
  4. 创建节点 creatElement(‘li’)
  5. 插入节点 ol.appendChild(li)
  6. 第一个小圆圈需要添加current类
代码段:
// 3.动态生成小圆圈  有几张图片,我们就生成几个小圆圈
 var ul=focus.querySelector('ul');
 var ol=focus.querySelector('ol');
 for(var i=0;i<ul.children.length;i++){
  // 创建一个小li
  var li=document.createElement('li');
  // 把小li插入到ol里面
  ol.appendChild(li);
//把ol里面的第一个小li设置类名为current
  ol.children[0].className='current';
step 3:
// 4.点击当前的小li 设置current 类名 (排他思想)
  li.addEventListener('click',function(){
   // 干掉所有人 把所有的小li 清除current类名
   for (var i=0;i<ul.children.length ;i++){
    ol.children[i].className='';
   }
   // 留下我自己  当前的小li 设置current 类名
   this.className='current';
  });
step 4:点击小圆圈滚动图片
分析:
  1. 此时用到animate动画函数,将js文件引入(注意:因为index.js依赖animate.js 所以,animate.js要写到index.js上面)
  2. 使用动画函数的前提,该元素必须有定位
  3. 注意是ul移动 而不是小li
  4. 滚动图片的核心算法:点击某个小圆圈,就让图片滚动 小圆圈的索引号乘以图片的宽度 做为ul移动距离
  5. 此时需要知道小圆圈的索引号,我们可以在生成小圆圈的时候,给他设置一个自定义属性,点击的时候就获取这个自定义属性即可。
代码段:
//记录当前小圆圈的索引号 通过自定义属性来做
  li.setAttribute('index',i); //这里!!漏了
//5.点击小圆圈,移动图片 移动的是ul
//ul 的移动距离 小圆圈的索引号 乘以 图片的宽度 (注意:是负值)
//当我们点击了某个小li 就拿到当前小li的 索引号
  var index=this.getAttrbute('index');
  animate(ul,-index*focusWidth);
step 5-1:点击右侧按钮一次,图片往左播放一张
分析:
  1. 声明一个unm变量(专门控制),点击一次 自增1 让这个变量乘以图片宽度,就是ul 的滚动距离。
  2. 图片无缝滚动原理 (把 ul第一个li复制一份,放到ul 的最后面)
  3. 当图片滚动到克隆的最后一张图片时,让ul 快速的、不做动画的跳到最左侧:left为0
  4. 同时将unm赋值为0,可以从新开始滚动图片了
代码段:
//6.克隆第一张图片(li)放到ul 最后面
var first=ul.children[0].cloneNode(true);
ul.appendChild(first);
// 7.点击右侧按钮,图片滚动一张
var num=0;
arrow_r.addEventListener('click',function(){
 //如果走到最后复制的一张图片,
 //此时,我们的ul 要快速复原 left 改为 0
 if (num==ul.children.length-1) {
  ul.style.left=0 + 'px';
  num=0;
 }
num++;
animate(ul,-num*focusWidth);
});
step 5-2:点击左侧按钮一次,图片往右播放一张
同理
代码段:
arrow_l.addEventListener('click',function(){
 if (num==0) {
  num=ul.children.length-1;
  ul.style.left= -num*focusWidth+'px'; 
 }
 num--;
 animate(ul,-num*focusWidth); //这边也要负数!
});
step6-1 :小圆圈跟随右侧按钮一起变化
分析:
  1. 最简单的做法是在声明一个变量circle,每次点击自增1,(注意,左侧按钮也需要这个变量,因此要声明为全局变量。)
  2. 但是图片有5张,我们小圆圈只有4个少一个,必须加一个半段条件
  3. 如果circle==4 就从新复原为 0。
代码段:
// 8.点击右侧按钮,小圆圈跟随一起变化 可以在声明一个变量控制小圆圈的播放
circle++;
if(circle==ol.children.length){
 circle=0;
}
for(var i=0;i<ol.children.length;i++){
 // 先清除其余小圆圈的current类名
 ol.children[i].className='';
}
// 留下当前的小圆圈的current类名
ol.children[circle].className='current';
});
step6-2 :小圆圈跟随左侧按钮一起变化
同理
代码段:
if (circle==0) {
  circle=ol.children.length;
 }
 circle--; //这里!要放在判断之后(也可以改成判断circle<0 就不用放后面 关系不大)
 for(var i=0;i<ol.children.length;i++){
  ol.children[i].className='';
 }
 ol.children[circle].className='current';
step6-3 :将共有的一段代码封装起来,改成函数调用
function circleChange (){
for(var i=0;i<ol.children.length;i++){
 // 先清除其余小圆圈的current类名
 ol.children[i].className='';
}
// 留下当前的小圆圈的current类名
ol.children[circle].className='current';
}
step7 :修补两个bug
分析:

num、circle和index是独立的 所以存在小圆圈不按顺序的情况
因此

 // 当我们点击了某个小li 就要把这个li 的索引号给 num
 num=index;
 // 当我们点击了某个小li 就要把这个li 的索引号给 circle
    circle=index;
step8 :鼠标不经过轮播图时,轮播图会自动播放图片。
分析:
  1. 添加一个定时器
  2. 自动播放轮播图,实际就类似于点击了右侧按钮
  3. 此时我们使用手动调用右侧按钮点击事件 arrow_r.click()
代码段:
// 10.自动播放轮播图
var timer=setInterval(function(){
 // 手动调用点击事件
 arrow_r.click();
},2000);
step9 :防止轮播图按钮连续点击造成播放过快
分析:
  1. 节流阀的目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法接连触发。
  2. 核心实现思路:利用一个回调函数,添加一个变量来控制,锁住函数和解锁函数。
  3. 开始设置一个变量 var flag=true;
  4. if (flag){flag=false;do someing} 关闭水龙头
  5. 利用回调函数 动画执行完毕,flag=true 打开水龙头
代码段:
arrow_r.addEventListener('click',function(){
 if(flag){
  flag=false;//关闭节流阀
  //如果走到最后复制的一张图片,此时,我们的ul 要快速复原left 改为 0
 if (num==ul.children.length-1) {
  ul.style.left=0+'px';
  num=0;
 }
num++;
animate(ul,-num*focusWidth,function(){
 flag=true;//打开节流阀
});
// 8.点击右侧按钮,小圆圈跟随一起变化 可以在声明一个变量控制小圆圈的播放
circle++;
if(circle==ol.children.length){
 circle=0;
}
circleChange();
 }
 });

二、 完整JS代码:

window.addEventListener('load',function(){
// 1.获取元素
 var arrow_r=document.querySelector('.arrow-r');
 var arrow_l=document.querySelector('.arrow-l');
 var focus =document.querySelector('.focus');
 var focusWidth=focus.offsetWidth;
 
 // 2.鼠标经过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 ';
 });
 // 3.动态生成小圆圈  有几张图片,我们就生成几个小圆圈
 var ul=focus.querySelector('ul');
 var ol=focus.querySelector('ol');
 for(var i=0;i<ul.children.length;i++){
  // 创建一个小li
  var li=document.createElement('li');
  //记录当前小圆圈的索引号 通过自定义属性来做
  li.setAttribute('index',i); //这里!!漏了
  // 把小li插入到ol里面
  ol.appendChild(li);
  
// 4.点击当前的小li 设置current 类名 (排他思想)
  li.addEventListener('click',function(){
   // 干掉所有人 把所有的小li 清除current类名
   for (var i=0;i<ol.children.length ;i++){
    ol.children[i].className='';
   }
   // 留下我自己  当前的小li 设置current 类名
 this.className='current';
 //5.点击小圆圈,移动图片 移动的是ul
    //ul 的移动距离 小圆圈的索引号 乘以 图片的宽度 (注意:是负值)
    //当我们点击了某个小li 就拿到当前小li的 索引号
 var index =this.getAttribute('index');
 // 当我们点击了某个小li 就要把这个li 的索引号给 num
 num=index;
 // 当我们点击了某个小li 就要把这个li 的索引号给 circle
    circle=index;
    console.log(num);
console.log(circle);
 console.log(index);
 console.log(focusWidth);
 animate(ul, -index * focusWidth);
})
 }
//把ol里面的第一个小li设置类名为current
     ol.children[0].className='current';
//6.克隆第一张图片(li)放到ul 最后面
var first=ul.children[0].cloneNode(true);
ul.appendChild(first);

// 7.点击右侧按钮,图片滚动一张
var num=0;
var circle=0;
var flag=true;
arrow_r.addEventListener('click',function(){
 if(flag){
  flag=false;//关闭节流阀
  //如果走到最后复制的一张图片,此时,我们的ul 要快速复原left 改为 0
 if (num==ul.children.length-1) {
  ul.style.left=0+'px';
  num=0;
 }
num++;
animate(ul,-num*focusWidth,function(){
 flag=true;//打开节流阀
});
// 8.点击右侧按钮,小圆圈跟随一起变化 可以在声明一个变量控制小圆圈的播放
circle++;
if(circle==ol.children.length){
 circle=0;
}
circleChange();
 }
 });
 // 9.左侧按钮做法
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 < 0  说明第一张图片,则小圆圈要改为第4个小圆圈(3)
 if (circle==0) {
  circle=ol.children.length;
 }
 circle--;
 circleChange();
 });
//简化代码,省得复制两次这个代码
function circleChange (){
for(var i=0;i<ol.children.length;i++){
 // 先清除其余小圆圈的current类名
 ol.children[i].className='';
}
// 留下当前的小圆圈的current类名
ol.children[circle].className='current';
}
// 10.自动播放轮播图
var timer=setInterval(function(){
 // 手动调用点击事件
 arrow_r.click();
},2000);
}) 

Leaning from pink 老师。
pink 老师说:“这个代码可能一辈子最多只会写一次”。所以我就认真的感受一下,记录一下,以后就直接ctrl+c&ctrl+v 啦~

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值