一、轮播图
1.PC端轮播图
(1).动画原理效果实现
<style>
.one{
width: 200px;
height: 200px;
background-color: aqua;
position:absolute;
margin-top: 100px;
}
.two{
width: 200px;
height: 200px;
background-color: blueviolet;
position:absolute;
}
</style>
</head>
<body>
<div class="one">
</div>
<button class="four">点击回到400</button>
<button class="eight">点击回到800</button>
<!-- <span class="two"></span> -->
<script>
//动画原理就是
//1.设置一个定时器
//2.写改变位置的函数,也就是它和左边的距离
//定时器每隔一段时间就会调用一次,不断改变左值,达到移动的效果
var one=document.querySelector('.one');
var four=document.querySelector('.four');
var eight=document.querySelector('.eight');
//callback,为回调函数,其实就相当于,把函数当作参数传入当前函数,
//当前函数执行完成后,会实现该函数
function animate(obj,target,callback)
{
//为了防止多次点击产生多个定时器,所以每次先清除以前的定时器
clearInterval(obj.timer)
//注意obj是一个对象,我们可以给这个对象添加属性,所以这里不用var timer,
obj.timer=setInterval(function(){
//加math.ceil是向上取整,这样就能保证,我们到达了指定位置,而不是有小数,和目标距离差一点
var step=(target-obj.offsetLeft)/10
//当我们在多个目标之间移动的时候,由于step会出现负值的情况,
//但是我们是数字大小往上取整,所以需要先判断step大小,正数向上,负数向下取整,才能保证最后我们到达目标位置
step=step>0?Math.ceil(step):Math.floor(step)
if(obj.offsetLeft==target)
{
//停止调用,本质是停止调用计时器
clearInterval(obj.timer);
//回调函数写到定时器结束里面
if(callback)
{
callback();
}
}
obj.style.left=obj.offsetLeft+step+'px';
}, 15);
}
four.addEventListener('click',function(){
animate(one,400,function(){
one.style.backgroundColor='pink'
});
})
eight.addEventListener('click',function(){
animate(one,800);
})
</script>
</body>
</html>
(2)无缝滚动
想要实现播放最后一张图片的时候,回到第一张。所以我们在最后再次添加第一张图片,同时,由于执行速度很快,我们虽然在最后一张,但是我们让其回到了第一张,以此来实现无缝滚动
想要动态生成最后一张图片,并且不会影响到我们小圆圈的生成数量,这里我们在动态创建完成小圆圈之后,克隆第一张图片,添加ul到最后
克隆:cloneNode(),括号里面写true为深克隆,false为浅克隆
(3)两个小bug
①移动方向和右键点击方向不一致,造成图片出现错误
就是要保证点击小圆圈的同时,也注意修改num,num要是当前的角标值—index。因为num在右键点击过程中,控制移动距离,相当于li点击中的index。
②小圆圈应该出现位置和右键点击方向不一致
因为circle控制小圆点变化情况,只有点击右键的时候circle才会变化。所以当我们点击li之后,circle没有变化,会导致小圆圈出现错误。所以我们也需要获取当前li的index,保证小圆圈和li出现对的上,circle=index;
(4).实现自动播放功能
这里相当于自动点击右键,所以我们而没必要重写一遍动画
此时我们使用手动调用右键点击事件——arrowright.click()
(5)节流阀
回调函数写法:中断
(6)完整轮播图代码
<!DOCTYPE html>
<html lang="zh-CN">
<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">
<title>轮播图</title>
<style>
/* 设置外边距为0 */
body,
ul,
ol {
margin: 0;
padding: 0;
}
/* 设置左右箭头格式 */
a {
position: absolute;
text-decoration: none;
font-size: 100px;
/* 这里是层级的意思 */
z-index: 2;
display: none;
}
a:nth-child(1) {
color: bisque;
top: 250px;
left: 0px;
}
a:nth-child(2) {
color: bisque;
top: 250px;
right: 0px;
}
/* 样式为none,就不会出现小圆点,数字等前面的格式 */
ul,
ol {
list-style: none;
}
.focus {
position: relative;
width: 1000px;
height: 600px;
overflow: hidden;
margin: auto;
}
ul {
position: absolute;
width: 500%;
}
img{
float: left;
width: 1000px;
height: 600px;
}
ol {
position: absolute;
bottom: 10px;
left: 104px;
margin: auto;
}
/* 小圆点样式 */
ol li {
float: left;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #fff;
margin-left: 5px;
box-sizing: border-box;
padding: 1px soild #fff;
}
/* 当前小圆点样式 */
.current {
background-color: transparent;
border: 2px solid #fff;
}
</style>
</head>
<body>
<div class="focus">
<!-- 左右两个可以切换的箭头 -->
<a href="#" class="arrowleft"><</a>
<a href="#" class="arrowright">></a>
<ul>
<li><img src="./风景图1.jpeg" alt=""></li>
<li><img src="./风景图2.jpeg" alt=""></li>
<li><img src="./风景图3.jpeg" alt=""></li>
<li><img src="./风景图4.jpeg" alt=""></li>
</ul>
<ol>
</ol>
</div>
<script>
//动画函数
function animate(obj,target,callback)
{
clearInterval(obj.timer)
obj.timer=setInterval(function(){
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();
}
}
obj.style.left=obj.offsetLeft+step+'px';
}, 15);
}
// 获取左右两个箭头
var arrowleft=document.querySelector('.arrowleft');
var arrowright=document.querySelector('.arrowright');
//获取整个大盒子
var focus=document.querySelector('.focus');
var focusWidth=focus.offsetWidth;//盒子长度,方面一会儿实现动画效果
//当鼠标进入的时候就显示左右箭头
focus.addEventListener('mouseenter',function(){
arrowleft.style.display='block';
arrowright.style.display='block';
clearInterval(timer)//停止自动播放
timer=null;//清除定时器
})
//当鼠标离开时,就隐藏左右箭头
focus.addEventListener('mouseleave',function(){
arrowleft.style.display='none';
arrowright.style.display='none';
timer=setInterval(function(){
arrowright.click();
},2000)
})
var ul=focus.querySelector('ul');
var ol=focus.querySelector('ol');
var num=0;
var circle=0
for(var i=0;i<ul.children.length;i++)
{
//创建li
var li=document.createElement('li');
//插入进ol
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');
num=index;
circle=index;
//解决上述bug
animate(ul,-index*focusWidth);
})
}
//由于打开页面时,我们就处在第一个界面,所以第一个小圆圈要为current
ol.children[0].className='current';
var first=ul.children[0].cloneNode(true);
ul.appendChild(first);
//右侧点击
var flag=true;//节流阀
arrowright.addEventListener('click',function(){
if(flag)
{
flag=false;
//无缝滚动
if(num==ul.children.length-1)
{
ul.style.left=0;
num=0
}
num++;
circle++;
animate(ul,-num*focusWidth,function(){
flag=true;//打开节流阀,必须在此函数执行完毕之后,才会进行,就相当于必须看完当前动画,才可以进行下一次点击
});
if(circle==4)
{
circle=0;
}
for(var i=0;i<ol.children.length;i++)
{
ol.children[i].className='';
}
ol.children[circle].className='current';
//为什么这里的角标不直接用num,因为num是图片数量,图片数量和小圆点数量不符合。如果我们使用num,在第五张时,由于小圆点不存在此角标,所以所有的小圆点都不会变化下一次num变成了2,所以跳转显示第一张图片时小圆点都一样,只有当又开始第二张,第三张,小圆点才会变成current
}
})
//左侧按钮
arrowleft.addEventListener('click',function(){
if(flag)
{
flag=false;
if(num==0)
{
num=ul.children.length-1;
ul.style.right=-num*focusWidth;
//注意负号,因为是ul左侧距离div的距离
}
num--;
circle--;
animate(ul,-num*focusWidth,function()
{
flag=true;
});
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';
}
})
//自动播放
var timer=setInterval(function(){
//这里我们发现,相当于自动点击了右侧按钮
arrowright.click();
},2000)
</Script>
</body>
</html>
案例
1.返回顶部
<script>
var backtotop=document.querySelector('.backtotop');
backtotop.addEventListener('click',function(){
// window.scroll(0,0);//(x,y)的意思,可以返回到window某个位置
animate(window,0);
});
function animate(obj,target,callback)
{
clearInterval(obj.timer)
obj.timer=setInterval(function(){
var step=(target-window.pageYOffset)/10
step=step>0?Math.ceil(step):Math.floor(step)
if(window.pageYOffset==target)
{
clearInterval(obj.timer);
if(callback)
{
callback();
}
}
window.scroll(0,window.pageYOffset+step);
}, 15);
}
</script>
2.移动端轮播图
(1)①transition:给自动播放添加过渡效果
例: ul.style.transition='all .3s';
②transitionend:监听过度完成事件
例:ul.addEventListener('transitionend',function(){})
(2)classList属性
实现:
添加与删除类名:
切换类:.classList.toggle('类名')
就是如果原来有这个类名,就给你删除,没有这个类名就给你增加
(3)移动端轮播图JS代码
<script>
var flag=false;//用于判断手指是否移动,若没有移动,就没有必要进行更多的计算
var ol=document.querySelector('ol');
var ul=document.querySelector('ul');
var focus=document.querySelector('.focus');
var focusWidth=focus.offsetWidth;
var index=0;
var timer=setInterval(function(){
index++;
var translatex=-index*focusWidth;
//添加过渡
ul.style.transition='all .3s';
ul.style.transform='translateX('+translatex+'px)';
},1000);
ul.addEventListener('transitionend',function()
{
//无缝滚动
if(index==4)
{
index=0;
//此时我们需要快速跳回第一张图片,所以我们要去掉过渡效果
ul.style.transition='none';
var translateX=-index*focusWidth;
ul.style.transform='translateX('+translateX+'px)'
}
else if(index<0)
{
index=2;
ul.style.transition='none';
var translateX=-index*focusWidth;
ul.style.transform='translateX('+translateX+'px)'
}
//把ol里面的li带有current的类名选出来,去掉类名,就不用排他循环的写法了
ol.querySelector('.current').classList.remove('current');
ol.children[index].classList.add('current')
})
//手指滑动轮播图
//触摸
var start=0;
var move=0;
ul.addEventListener('touchstart',function(e)
{
start=e.targetTouches[0].pageX;
clearInterval(timer);
})
//计算手指滑动距离
ul.addEventListener('touchmove',function(e)
{
move=e.targetTouches[0].pageX-start;
//手指拖动的时候不需要动画效果,所以要取消过渡
ul.style.transition='none';
var translateX=-index*focusWidth+move;
ul.style.transform='translateX('+translateX+'px)'
flag=true;
e.preventDefault();//阻止滚动屏幕的行为
})
ul.addEventListener('touchend',function()
{
if(flag)
{
if(Math.abs(move)>50)
{
//右划,播放上一张,move为负值(move是末位置-初位置)
if(move>0)
{
index--;
}
else{
index++;
}
ul.style.transition='all .3s';
var translateX=-index*focusWidth;
ul.style.transform='translateX('+translateX+'px)'
}
//假如滑动距离小,那么我们就回弹回当前图片
else{
var translateX=-index*focusWidth;
ul.style.transition='all .3s';
ul.style.transform='translateX('+translateX+'px)'
}
//手指离开后继续启动定时器
clearInterval(timer);
timer=setInterval(function(){
index++;
var translatex=-index*focusWidth;
//添加过渡
ul.style.transition='all .3s';
ul.style.transform='translateX('+translatex+'px)';
},1000);
}
})
</script>
(4)click延时问题
移动端click事件会有300ms的延时,原因是移动端屏幕双击会缩放(doube tap to zoom)页面。就是说,当你点击之后,会有300ms,判断你是否继续点击,如果有就进行缩放页面。
解决方案:
①
②
二、插件
1.移动端常用开发插件
①插件
解决延时问题的插件:fastclick
使用:
插件:新建js文件
引用和具体语法规范
DOMContentLoaded:意思就是等着页面所有元素加载完成之后再进行
复制这段代码之后,就可以照常写我们想要做的事情了。
2.Swiper插件的使用
(1)网址:Swiper官网
(2)使用:
①先引入相关文件
注意一定要先引用swiper的js再引用我们自己的js文件
②按照语法规定使用它
打开demo,查看其中html如何写的,我们按照它写的方法,复制粘贴,把其中内容改成我们想要的东西,注意不要改变相关类名。可以在官网查看相关使用方法
若想修改某个样式的方法:
自己写css,置顶其重要性
比如:
.类名{
想要修改的样式: !important;
}
如:
.div{
background:#fff!important;//此时,不管原先bcg是什么颜色,都被修改成了白色
}
(3)其他常见插件
superslide、iscroll
插件使用总结:
三、框架
四、本地存储
1.本地存储特性
2.window.sessionStorage
检查之后点击Application—Session Storage就可以查看我们的数据了
例: