文章目录
一、无缝滑屏轮播组件(使用定位)
1、不是无缝的滑屏轮播
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0" /> -->
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no"/>
<title></title>
<style type="text/css">
*{margin: 0;padding: 0;}
html,body{height: 100%;overflow: hidden;}
#wrap{height: 100%;overflow: hidden;}
#wrap .carouse_wrap > .list{list-style: none;overflow: hidden;position: absolute;}
#wrap .carouse_wrap > .list > li{float: left;}
#wrap .carouse_wrap > .list > li > a,#wrap .carouse_wrap > .list > li > a > img{display: block;}
#wrap .carouse_wrap > .list > li > a > img{width: 100%;}
</style>
</head>
<body>
<div id="wrap"><!-- 用来布局的,包裹轮播图,设置轮播图在页面位置 -->
<div class="carouse_wrap"><!-- 轮播容器 -->
</div>
</div>
</body>
<script type="text/javascript">
window.onload=function(){
/* 全局禁用默认事件触发 */
document.addEventListener("touchstart",function(ev){
ev=event||ev;
ev.preventDefault();
});
/* 动态生成轮播图 */
let arr = ["img/01.jpg","img/02.jpg","img/03.jpg","img/04.jpg","img/05.jpg"];//模拟从后台获取的轮播图列表
let carouse_wrap = document.querySelector(".carouse_wrap");//获取轮播容器
if(carouse_wrap){//如果轮播存在
/* dom结点 */
let ul = document.createElement("ul"); //创建一个ul结点
let style = document.createElement("style");//创建一个style结点
let head = document.querySelector("head"); //获取head结点
ul.classList.add("list") //给创建的ul的class列表添加一个.list样式
for(let i = 0;i<arr.length;i++){//遍历数组,有多少图片就添加多少轮播结构
ul.innerHTML+='<li><a href="javascript:;"><img src="'+arr[i]+'" ></a></li>'
}
carouse_wrap.appendChild(ul) //把ul添加到容器中
/* (重点)给style结点添加样式,首先
我们应该先确定单张图片的大小,这里我就直接用百分比让图片填满屏幕了
那么,我们应该让ul的宽度正好容纳这些轮播图片,比如5张图片就是500%
那么5张图片,每张就占ul的20%,5*20%=100%,正好填满ul
*/
style.innerHTML="#wrap .carouse_wrap > .list{width: "+arr.length*100+"%;}#wrap .carouse_wrap > .list > li{width: "+100/arr.length+"%;}"
head.appendChild(style)//将style结点添加到head中
/* 最后,因为每个li都设置的定位,容器就没有东西撑开造成高度塌陷,我们只需要让其等于图片高度即可 */
let img = document.querySelector("#wrap .carouse_wrap > .list > li:nth-of-type(1) > a > img");
let timer=setTimeout(function(){/* 因为js代码执行很快,页面没渲染好就获取offsetHeight会获取不到,等100ms就可以了 */
carouse_wrap.style.height=img.offsetHeight+"px"
},100)
clearTimeout(timer)//清除
/* ==================创建轮播完================= */
/* ==================滑屏======================= */
let ElStartX = 0; //元素当前位置
let startX = 0; //记录手点击起始位置
let moveX = 0; //记录手指滑动距离
let endX = 0; //记录手指抬起时位置
let index = 0; //记录当前轮播的下标
/* 手指点击屏幕事件 获取手指和当前元素位置*/
carouse_wrap.addEventListener("touchstart",function(ev){
ev = event||ev;
startX = ev.changedTouches[0].clientX;//获取手指点击位置
ElStartX = ul.offsetLeft;//获取元素当前位置
})
/* 手指移动事件 让元素跟随手指移动*/
carouse_wrap.addEventListener("touchmove",function(ev){
ev = ev||event;
ul.style.transition="none"; //清除过渡,在手指抬起事件中绑定,这里要清掉,因为影响滑屏体验
let nowX = ev.changedTouches[0].clientX; //获取滑动时的位置
moveX = nowX - startX; //获取滑动距离
ul.style.left = ElStartX + moveX + "px"; //让ul跟随手指偏移
})
/* 手指抬起事件 判断移动距离,如果超过100px的距离,就让轮播跳转到下一张或上一张,第一张和最后一张怎么滑都会回到原来的位置*/
carouse_wrap.addEventListener("touchend",function(ev){
ev = ev||event;
if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
index===0?index=0:index--; //如果index=0了就让index=4,否则就自减
}else if(moveX < 0 && moveX <= -100){
index===4?index=4:index++;
}
ul.style.transition="1s left";//设置动画,在手指抬起时才设置
ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
/* 方式2
let index = ul.offsetLeft/img.offsetWidth;//获取实时的位置,用ul的当前偏移/轮播宽度,就会得到一个数
这个数如果你向右滑屏会得到一个正数,如果你刚好滑满一屏,就是1,否则是一个小数
if(moveX > 0){
index = Math.ceil(index);//返回大于或等于index的最小整数
}else if(moveX < 0){
index = Math.floor(index);//返回小于或等于index的最大整数
}
ul.style.left = index * img.offsetWidth+"px"
*/
})
}
}
</script>
</html>
2、组件化无缝滑屏轮播(用户可以通过指定参数来决定是否需要无缝功能)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0" /> -->
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no"/>
<title></title>
<style type="text/css">
*{margin: 0;padding: 0;}
html,body{height: 100%;overflow: hidden;}
#wrap{height: 100%;overflow: hidden;}
#wrap .carouse_wrap > .list{list-style: none;overflow: hidden;position: absolute;}
#wrap .carouse_wrap > .list > li{float: left;}
#wrap .carouse_wrap > .list > li > a,#wrap .carouse_wrap > .list > li > a > img{display: block;}
#wrap .carouse_wrap > .list > li > a > img{width: 100%;}
</style>
</head>
<body>
<div id="wrap"><!-- 用来布局的,包裹轮播图,设置轮播图在页面位置 -->
<div class="carouse_wrap" ><!-- 轮播容器 -->
</div>
</div>
</body>
<script type="text/javascript">
window.onload=function(){
/* 全局禁用默认事件触发 */
document.addEventListener("touchstart",function(ev){
ev=event||ev;
ev.preventDefault();
});
/* 动态生成轮播图 */
let arr = ["img/01.jpg","img/02.jpg","img/03.jpg","img/04.jpg","img/05.jpg"];//模拟从后台获取的轮播图列表
let carouse_wrap = document.querySelector(".carouse_wrap");//获取轮播容器
if(carouse_wrap){//如果轮播存在
/* 无缝1、复制数组 并确定用户是否需要无缝功能*/
/*
看看<div class="carouse_wrap" needCarouse >,加没加needCarouse,如果加了,表示用户需要无缝功能,没加就是null表示不需要无缝
*/
let needCarouse = carouse_wrap.getAttribute("needCarouse");//判断用户是否需要无缝功能
if(needCarouse!=null){/* 如果不是null,表示需要无缝功能 */
let arrLength = arr.length;//保存当前数组的长度,因为复制数组会让数组长度改变
arr = arr.concat(arr)//向arr数组后面添加数组arr,生成一个全新的数组,然后重新赋值给arr
}
/* dom结点 */
let ul = document.createElement("ul"); //创建一个ul结点
let style = document.createElement("style");//创建一个style结点
let head = document.querySelector("head"); //获取head结点
ul.classList.add("list") //给创建的ul的class列表添加一个.list样式
for(let i = 0;i<arr.length;i++){//遍历数组,有多少图片就添加多少轮播结构
ul.innerHTML+='<li><a href="javascript:;"><img src="'+arr[i]+'" ></a></li>'
}
carouse_wrap.appendChild(ul) //把ul添加到容器中
/* (重点)给style结点添加样式,首先
我们应该先确定单张图片的大小,这里我就直接用百分比让图片填满屏幕了
那么,我们应该让ul的宽度正好容纳这些轮播图片,比如5张图片就是500%
那么5张图片,每张就占ul的20%,5*20%=100%,正好填满ul
*/
style.innerHTML="#wrap .carouse_wrap > .list{width: "+arr.length*100+"%;}#wrap .carouse_wrap > .list > li{width: "+100/arr.length+"%;}"
head.appendChild(style)//将style结点添加到head中
/* 最后,因为每个li都设置的定位,容器就没有东西撑开造成高度塌陷,我们只需要让其等于图片高度即可 */
let img = document.querySelector("#wrap .carouse_wrap > .list > li:nth-of-type(1) > a > img");
let timer=setTimeout(function(){/* 因为js代码执行很快,页面没渲染好就获取offsetHeight会获取不到,等100ms就可以了 */
carouse_wrap.style.height=img.offsetHeight+"px"
},100)
clearTimeout(timer)//清除
/* ==================创建轮播完================= */
/* ==================滑屏======================= */
let ElStartX = 0; //元素当前位置
let startX = 0; //记录手点击起始位置
let moveX = 0; //记录手指滑动距离
let endX = 0; //记录手指抬起时位置
let index = 0; //记录当前轮播的下标
/* 手指点击屏幕事件 获取手指和当前元素位置*/
carouse_wrap.addEventListener("touchstart",function(ev){
ev = event||ev;
ElStartX = ul.offsetLeft;//获取元素当前位置
startX = ev.changedTouches[0].clientX;//获取手指点击位置
ul.style.transition="none"; //清除过渡,在手指抬起事件中绑定,这里要清掉,因为影响滑屏体验
/* ===========无缝滑屏2======== */
if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
if(index===0){/* 如果是第一个数组第一张 */
moveX = 0; //重新定位需要清除刚刚算出来的滑动距离
index=arr.length/2 //如果当前是第一张轮播图让index瞬间变为第二个数组的第一张
ElStartX=-index * img.offsetWidth; //起始位置变为第二个数组第一张
ul.style.left = -index * img.offsetWidth+"px"; //ul偏移到第二个数组第一张
}else if(index===(arr.length-1)){/* 如果是第二个数组最后一张 */
index=arr.length/2-1 //让index瞬间变为第一个数组最后一张
ElStartX=-index * img.offsetWidth; //起始位置变为第一个数组最后一张
ul.style.left = -index * img.offsetWidth+"px"; //偏移到第一个数组最后一张
}else{/* 如果不是第一和最后一张,普通的获取值即可 */
ElStartX = ul.offsetLeft;//获取元素当前位置
}
}else{/* 是null表示不需要 */
ElStartX = ul.offsetLeft;//获取元素当前位置
}
})
/* 手指移动事件 让元素跟随手指移动*/
carouse_wrap.addEventListener("touchmove",function(ev){
ev = ev||event;
let nowX = ev.changedTouches[0].clientX; //获取滑动时的位置
moveX = nowX - startX; //获取滑动距离
ul.style.left = ElStartX + moveX + "px"; //让ul跟随手指偏移
})
/* 手指抬起事件 判断移动距离,如果超过100px的距离,就让轮播跳转到下一张或上一张,第一张和最后一张怎么滑都会回到原来的位置*/
carouse_wrap.addEventListener("touchend",function(ev){
ev = ev||event;
/* 无缝滑屏3,改改逻辑 */
if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
index--;
}else if(moveX < 0 && moveX <= -100){
index++;
}
}else{
if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
index===0?index=0:index--; //如果index=0了就让index=4,否则就自减
}else if(moveX < 0 && moveX <= -100){
index===4?index=4:index++;
}
}
ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
})
}
}
</script>
</html>
3、组件化自动轮播功能,用户可选功能
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0" /> -->
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<meta name="format-detection" content="telephone=no,email=no"/>
<title></title>
<style type="text/css">
*{margin: 0;padding: 0;}
html,body{height: 100%;overflow: hidden;}
#wrap{height: 100%;overflow: hidden;}
#wrap .carouse_wrap > .list{list-style: none;overflow: hidden;position: absolute;}
#wrap .carouse_wrap > .list > li{float: left;}
#wrap .carouse_wrap > .list > li > a,#wrap .carouse_wrap > .list > li > a > img{display: block;}
#wrap .carouse_wrap > .list > li > a > img{width: 100%;}
</style>
</head>
<body>
<div id="wrap"><!-- 用来布局的,包裹轮播图,设置轮播图在页面位置 -->
<div class="carouse_wrap" needCarouse needAutoCarouse ><!-- 轮播容器 -->
</div>
</div>
</body>
<script type="text/javascript">
window.onload=function(){
/* 全局禁用默认事件触发 */
document.addEventListener("touchstart",function(ev){
ev=event||ev;
ev.preventDefault();
});
/* 动态生成轮播图 */
let arr = ["img/01.jpg","img/02.jpg","img/03.jpg","img/04.jpg","img/05.jpg"];//模拟从后台获取的轮播图列表
let carouse_wrap = document.querySelector(".carouse_wrap");//获取轮播容器
if(carouse_wrap){//如果轮播存在
/* 无缝1、复制数组 并确定用户是否需要无缝功能*/
/*
看看<div class="carouse_wrap" needCarouse >,加没加needCarouse,如果加了,表示用户需要无缝功能,没加就是null表示不需要无缝
*/
let needCarouse = carouse_wrap.getAttribute("needCarouse");//判断用户是否需要无缝功能
if(needCarouse!=null){/* 如果不是null,表示需要无缝功能 */
let arrLength = arr.length;//保存当前数组的长度,因为复制数组会让数组长度改变
arr = arr.concat(arr)//向arr数组后面添加数组arr,生成一个全新的数组,然后重新赋值给arr
}
/* &&&&&&&&&&&&&自动轮播1、&&&&&&&&&&&&&&&& */
let needAutoCarouse = carouse_wrap.getAttribute("needAutoCarouse");/* 如果有此参数,表示用户开启自动轮播 */
if(needAutoCarouse!=null){
let AutoTimer = 0;//用来保存自动轮播时间函数id
AutoCarouse(); //自动轮播函数
}
/* dom结点 */
let ul = document.createElement("ul"); //创建一个ul结点
let style = document.createElement("style");//创建一个style结点
let head = document.querySelector("head"); //获取head结点
ul.classList.add("list") //给创建的ul的class列表添加一个.list样式
for(let i = 0;i<arr.length;i++){//遍历数组,有多少图片就添加多少轮播结构
ul.innerHTML+='<li><a href="javascript:;"><img src="'+arr[i]+'" ></a></li>'
}
carouse_wrap.appendChild(ul) //把ul添加到容器中
/* (重点)给style结点添加样式,首先
我们应该先确定单张图片的大小,这里我就直接用百分比让图片填满屏幕了
那么,我们应该让ul的宽度正好容纳这些轮播图片,比如5张图片就是500%
那么5张图片,每张就占ul的20%,5*20%=100%,正好填满ul
*/
style.innerHTML="#wrap .carouse_wrap > .list{width: "+arr.length*100+"%;}#wrap .carouse_wrap > .list > li{width: "+100/arr.length+"%;}"
head.appendChild(style)//将style结点添加到head中
/* 最后,因为每个li都设置的定位,容器就没有东西撑开造成高度塌陷,我们只需要让其等于图片高度即可 */
let img = document.querySelector("#wrap .carouse_wrap > .list > li:nth-of-type(1) > a > img");
let timer=setTimeout(function(){/* 因为js代码执行很快,页面没渲染好就获取offsetHeight会获取不到,等100ms就可以了 */
carouse_wrap.style.height=img.offsetHeight+"px"
},100)
clearTimeout(timer)//清除
/* ==================创建轮播完================= */
/* ==================滑屏======================= */
let ElStartX = 0; //元素当前位置
let startX = 0; //记录手点击起始位置
let moveX = 0; //记录手指滑动距离
let endX = 0; //记录手指抬起时位置
let index = 0; //记录当前轮播的下标
/* 手指点击屏幕事件 获取手指和当前元素位置*/
carouse_wrap.addEventListener("touchstart",function(ev){
ev = event||ev;
/* &&&&&&&&&&&&自动轮播2&&&&&&&&&&&&&&& */
if(needAutoCarouse!=null){
clearInterval(AutoTimer)//点击时清除自动轮播
}
ElStartX = ul.offsetLeft;//获取元素当前位置
startX = ev.changedTouches[0].clientX;//获取手指点击位置
ul.style.transition="none"; //清除过渡,在手指抬起事件中绑定,这里要清掉,因为影响滑屏体验
/* ===========无缝滑屏2======== */
if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
moveX = 0;
if(index===0){/* 如果是第一个数组第一张 */
index=arr.length/2 //如果当前是第一张轮播图让index瞬间变为第二个数组的第一张
ElStartX=-index * img.offsetWidth; //起始位置变为第二个数组第一张
ul.style.left = -index * img.offsetWidth+"px"; //ul偏移到第二个数组第一张
}else if(index===(arr.length-1)){/* 如果是第二个数组最后一张 */
index=arr.length/2-1 //让index瞬间变为第一个数组最后一张
ElStartX=-index * img.offsetWidth; //起始位置变为第一个数组最后一张
ul.style.left = -index * img.offsetWidth+"px"; //偏移到第一个数组最后一张
}else{/* 如果不是第一和最后一张,普通的获取值即可 */
ElStartX = ul.offsetLeft;//获取元素当前位置
}
}else{/* 是null表示不需要 */
ElStartX = ul.offsetLeft;//获取元素当前位置
}
})
/* 手指移动事件 让元素跟随手指移动*/
carouse_wrap.addEventListener("touchmove",function(ev){
ev = ev||event;
let nowX = ev.changedTouches[0].clientX; //获取滑动时的位置
moveX = nowX - startX; //获取滑动距离
ul.style.left = ElStartX + moveX + "px"; //让ul跟随手指偏移
})
/* 手指抬起事件 判断移动距离,如果超过100px的距离,就让轮播跳转到下一张或上一张,第一张和最后一张怎么滑都会回到原来的位置*/
carouse_wrap.addEventListener("touchend",function(ev){
ev = ev||event;
/* 无缝滑屏3,改改逻辑 */
if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
index--;
}else if(moveX < 0 && moveX <= -100){
index++;
}
}else{
if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
index===0?index=0:index--; //如果index=0了就让index=4,否则就自减
}else if(moveX < 0 && moveX <= -100){
index===4?index=4:index++;
}
}
ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
/* &&&&&&&&&&&&&自动轮播3&&&&&&&&&&&&&&&& */
if(needAutoCarouse!=null){
AutoCarouse();//手指抬起时,重新启动自动轮播
}
})
function AutoCarouse(){
AutoTimer = setInterval(function(){
if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
if(index===arr.length-1){/* 如果是第二个数组最后一张 */
ul.style.transition="none";//设置动画,在手指抬起时才设置
index=arr.length/2-1 //让index瞬间变为第一个数组最后一张
ul.style.left = -index * img.offsetWidth+"px"; //偏移到第一个数组最后一张
}
setTimeout(function(){
index++
ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
},500)
}else{
index===arr.length-1?index=0:index++;
ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
}
},1000)
}
}
}
</script>
</html>
二、使用less来rem适配
首先你得了解如何适配 |
---|
设计稿尺寸为1080 |
1、新建less文件使用考拉打包
//css reset
html,body,h1,h2,h3,h4,h5,p,a,img,span,div,input,form,ul{margin: 0;padding: 0;}
html,body{height: 100%;overflow: hidden;}
ul{list-style: none;}
a{text-decoration: none;display: block;}
img{display: block;}
a,input,button{-webkit-tap-highlight-color: rgba(0,0,0,0);outline: none;border:0;}//禁用这3个元素的选中高亮显示
button{-webkit-appearance: none;}//禁用button的特殊样式
//首先,我们font-size的值是动态的那么1rem也是动态的,我这里通常1rem就是视图尺寸的1/16
//所以我们只需要让设计图尺寸1080/16rem,就可以得到设计图对应当前手机的rem尺寸,
//16rem是当前屏幕的像素大小,1080是设计图大小,1080/16rem,就可以获取到设计图对应到当前屏幕的一个比例
@rem:1080/16rem;
#wrap{
height: 100%;
overflow: auto;
.head{
position: absolute;
width: 100%;
height: 100px;
background-color: pink;
.logo {
img{
/* 方法一
适配logo大小,首先我们将屏幕分成了16rem,
而设计图大小为1080,logo大小240,240/1080=0.222222
0.222222*16rem=3.555555555555556rem
*/
// width: 3.555555555555556rem; 很麻烦有没有
/* 方法2
图片尺寸240,@rem是当前设计图占多少份rem
240/@rem=相应适配的rem值
*/
width:240/@rem;/* 240/67.5个rem,就是当前屏幕适配的rem */
}
}
}
}
2、页面引入
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<link rel="stylesheet" type="text/css" href="assets/css/index.css"/>
</head>
<body>
<div id="wrap">
<div class="head"><!-- 头部组件 -->
<div class="head-top"><!-- 头部组件的上面部分 -->
<h1 class="logo">
<a href="javascript:;">
<img src="assets/img/logo.png" >
</a>
</h1>
</div>
<div class="head-bottom"><!-- 头部组件下面的导航部分 -->
</div>
</div>
</div>
</body>
<script type="text/javascript">
window.onload=function(){
/* 全局禁用默认事件 */
document.addEventListener("touchstart",function(ev){
ev = ev||event;
ev.preventDefault();
});
/* 获取适配 */
(function(){
let style = document.createElement("style");//创建style结点
let width = document.documentElement.clientWidth/16;//让widht为视口的16分之一
style.innerHTML="html{font-size:"+width+"px !important}";//设置根标签字体大小
document.head.appendChild(style);//将其添加到head
})();
}
</script>
</html>
三、尚硅谷谷粒音乐实战,b站搜就有视频和配套资源
1、工具类
/* 专门用来给node节点改变className属性的 */
(function(w){
w.tools={};//暴露此对象,给window,同此对象来调用方法
tools.addClass=function(node,className){
let reg = new RegExp("\\b"+className+"\\b");//正则表达式,匹配所有className
if(!reg.test(node.className)){
node.className+=(" "+className);
}
}
tools.removeClass=function(node,className){
if(node.className){
let reg = new RegExp("\\b"+className+"\\b");
let classes = node.className;
node.className = classes.replace(reg,"");
if(/^\s*$/g.test(node.className)){
node.removeAttribute("class");
}
}else{
node.removeAttribute("class")
}
}
})(window)
2、无缝轮播
/* 动态生成轮播图 */
(function(w){
w.carouse={};
carouse.initCarouse=function(a){
let arr = a;//模拟从后台获取的轮播图列表
let carouse_wrap = document.querySelector(".carouse_wrap");//获取轮播容器
if(carouse_wrap){//如果轮播存在
/* 无缝1、复制数组 并确定用户是否需要无缝功能*/
/*
看看<div class="carouse_wrap" needCarouse >,加没加needCarouse,如果加了,表示用户需要无缝功能,没加就是null表示不需要无缝
*/
let needCarouse = carouse_wrap.getAttribute("needCarouse");//判断用户是否需要无缝功能
if(needCarouse!=null){/* 如果不是null,表示需要无缝功能 */
let arrLength = arr.length;//保存当前数组的长度,因为复制数组会让数组长度改变
arr = arr.concat(arr)//向arr数组后面添加数组arr,生成一个全新的数组,然后重新赋值给arr
}
/* &&&&&&&&&&&&&自动轮播1、&&&&&&&&&&&&&&&& */
let needAutoCarouse = carouse_wrap.getAttribute("needAutoCarouse");/* 如果有此参数,表示用户开启自动轮播 */
if(needAutoCarouse!=null){
let AutoTimer = 0;//用来保存自动轮播时间函数id
AutoCarouse(); //自动轮播函数
}
/* dom结点 */
let ul = document.createElement("ul"); //创建一个ul结点
let style = document.createElement("style");//创建一个style结点
let head = document.querySelector("head"); //获取head结点
ul.classList.add("list") //给创建的ul的class列表添加一个.list样式
ul.style.transform="translateZ(0)"; //开启3d硬件加速,只要开启3d就会跳过浏览器,使用硬件加载
for(let i = 0;i<arr.length;i++){//遍历数组,有多少图片就添加多少轮播结构
ul.innerHTML+='<li><a href="javascript:;"><img src="'+arr[i]+'" ></a></li>'
}
carouse_wrap.appendChild(ul) //把ul添加到容器中
/* (重点)给style结点添加样式,首先
我们应该先确定单张图片的大小,这里我就直接用百分比让图片填满屏幕了
那么,我们应该让ul的宽度正好容纳这些轮播图片,比如5张图片就是500%
那么5张图片,每张就占ul的20%,5*20%=100%,正好填满ul
*/
style.innerHTML="#wrap .carouse_wrap > .list{width: "+arr.length*100+"%;}#wrap .carouse_wrap > .list > li{width: "+100/arr.length+"%;}"
head.appendChild(style)//将style结点添加到head中
/* 最后,因为每个li都设置的定位,容器就没有东西撑开造成高度塌陷,我们只需要让其等于图片高度即可 */
let img = document.querySelector("#wrap .carouse_wrap > .list > li:nth-of-type(1) > a > img");
let timer=setTimeout(function(){/* 因为js代码执行很快,页面没渲染好就获取offsetHeight会获取不到,等100ms就可以了 */
carouse_wrap.style.height=img.offsetHeight+"px"
},100)
clearTimeout(timer)//清除
/* ==================创建轮播完================= */
/* ==================滑屏======================= */
let ElStartX = 0; //元素当前位置
let startX = 0; //记录手点击起始位置
let moveX = 0; //记录手指滑动距离
let endX = 0; //记录手指抬起时位置
let index = 0; //记录当前轮播的下标
/* 防抖动
判断用户首次滑屏方向
x轴
不管用户怎么滑都会抖
y轴
不管用户怎么滑都不会抖
*/
let startY = 0; //记录y轴,用来防抖动
let moveY = 0; //防抖动
let XOrY = true;//true表示x轴,false表示y轴
let first = true;//true表示首次滑,false表示不是首次滑
/* 手指点击屏幕事件 获取手指和当前元素位置*/
carouse_wrap.addEventListener("touchstart",function(ev){
ev = event||ev;
/* &&&&&&&&&&&&自动轮播2&&&&&&&&&&&&&&& */
if(needAutoCarouse!=null){
clearInterval(AutoTimer)//点击时清除自动轮播
}
ElStartX = ul.offsetLeft;//获取元素当前位置
startX = ev.changedTouches[0].clientX;//获取手指点击位置
startY = ev.changedTouches[0].clientY;//获取y轴位置,防抖动
ul.style.transition="none"; //清除过渡,在手指抬起事件中绑定,这里要清掉,因为影响滑屏体验
/* ===========无缝滑屏2======== */
if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
moveX = 0;
if(index===0){/* 如果是第一个数组第一张 */
index=arr.length/2 //如果当前是第一张轮播图让index瞬间变为第二个数组的第一张
ElStartX=-index * img.offsetWidth; //起始位置变为第二个数组第一张
ul.style.left = -index * img.offsetWidth+"px"; //ul偏移到第二个数组第一张
}else if(index===(arr.length-1)){/* 如果是第二个数组最后一张 */
index=arr.length/2-1 //让index瞬间变为第一个数组最后一张
ElStartX=-index * img.offsetWidth; //起始位置变为第一个数组最后一张
ul.style.left = -index * img.offsetWidth+"px"; //偏移到第一个数组最后一张
}else{/* 如果不是第一和最后一张,普通的获取值即可 */
ElStartX = ul.offsetLeft;//获取元素当前位置
}
}else{/* 是null表示不需要 */
ElStartX = ul.offsetLeft;//获取元素当前位置
}
})
/* 手指移动事件 让元素跟随手指移动*/
carouse_wrap.addEventListener("touchmove",function(ev){
ev = ev||event;
if(!XOrY){//放抖动=========如果首次在y轴滑,不执行下面逻辑
return;
}
let nowX = ev.changedTouches[0].clientX; //获取滑动时的位置
let nowY = ev.changedTouches[0].clientY; //防抖动,获取当前y轴位置
moveX = nowX - startX; //获取滑动距离
moveY = nowY - startY; //获取y轴滑动距离
/* 防抖动
判断用户首次滑屏方向
x轴
不管用户怎么滑都会抖
y轴
不管用户怎么滑都不会抖
*/
if(first){//如果是首次滑屏,判断是x轴滑还是y轴滑,不是首次就不在进行下面的判断
//让first = false;表示不是首次滑动了
first = false;
if(Math.abs(moveY)>Math.abs(moveX)){//如果y滑动距离比x大,说明是上下滑不是左右滑
XOrY = false;//表示首次滑屏为y轴
return;//如果是y轴,就不让它执行下面的偏移
}
}
ul.style.left = ElStartX + moveX + "px"; //让ul跟随手指偏移
})
/* 手指抬起事件 判断移动距离,如果超过100px的距离,就让轮播跳转到下一张或上一张,第一张和最后一张怎么滑都会回到原来的位置*/
carouse_wrap.addEventListener("touchend",function(ev){
ev = ev||event;
/* 防抖动 让XOrY重新置为true,first也变为true表示首次默认x轴 */
XOrY = true;
first = true;
/* 无缝滑屏3,改改逻辑 */
if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
index--;
}else if(moveX < 0 && moveX <= -100){
index++;
}
}else{
if(moveX > 0 && moveX >= 100){//>0表示向右滑动屏幕
index===0?index=0:index--; //如果index=0了就让index=4,否则就自减
}else if(moveX < 0 && moveX <= -100){
index===4?index=4:index++;
}
}
ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
/* &&&&&&&&&&&&&自动轮播3&&&&&&&&&&&&&&&& */
if(needAutoCarouse!=null){
AutoCarouse();//手指抬起时,重新启动自动轮播
}
})
function AutoCarouse(){
AutoTimer = setInterval(function(){
if(needCarouse!=null){//如果不为null表示用户需要无缝轮播
if(index===arr.length-1){/* 如果是第二个数组最后一张 */
ul.style.transition="none";//设置动画,在手指抬起时才设置
index=arr.length/2-1 //让index瞬间变为第一个数组最后一张
ul.style.left = -index * img.offsetWidth+"px"; //偏移到第一个数组最后一张
}
setTimeout(function(){
index++
ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
},500)
}else{
index===arr.length-1?index=0:index++;
ul.style.transition="0.5s left";//设置动画,在手指抬起时才设置
ul.style.left = -index * img.offsetWidth+"px";//让ul偏移当前图片下标*单张轮播宽度的距离
}
},1000)
}
}
}
})(window)
3、用来继承的less
.clearfix{
*zoom: 1;
&:after{
content: "";
display: block;
clear: both;
}
}
4、混合less
.1-px(top,@color:black){
position: relative;
&::before{
position: absolute;
content: "";
display: block;
top: 0;
width: 100%;
height: 1px;
background: @color;
@media only screen and (-webkit-device-pixel-ratio:2){
transform: scaleY(.5);
}
@media only screen and (-webkit-device-pixel-ratio:3){
transform: scaleY(.33333333);
}
}
}
.1-px(bottom,@color:black){
position: relative;
&::before{
position: absolute;
content: "";
display: block;
bottom: 0;
width: 100%;
height: 1px;
background: @color;
@media only screen and (-webkit-device-pixel-ratio:2){
transform: scaleY(.5);
}
@media only screen and (-webkit-device-pixel-ratio:3){
transform: scaleY(.33333333);
}
}
}
5、轮播图less
#wrap{
.carouse_wrap{
> .list{
list-style: none;
overflow: hidden;
position: relative;
> li{
float: left;
> a{
display: block;
> img{
display: block;
width: 100%;
}
}
}
}
}
}
6、主体less
//css reset
html,body,h1,h2,h3,h4,h5,p,a,img,span,div,input,form,ul{margin: 0;padding: 0;}
html,body{height: 100%;overflow: hidden;}
ul{list-style: none;}
a{text-decoration: none;display: block;}
img{display: block;}
a,input,button{-webkit-tap-highlight-color: rgba(0,0,0,0);outline: none;border: 0;}//禁用这3个元素的选中高亮显示
button{-webkit-appearance: none;}//禁用button的特殊样式
.txt {/* 禁用长按文字选中功能 */
-webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
//首先,我们font-size的值是动态的那么1rem也是动态的,我这里通常1rem就是视图尺寸的1/16
//所以我们只需要让设计图尺寸1080/16rem,就可以得到设计图对应当前手机的rem尺寸,
//16rem是当前屏幕的像素大小,1080是设计图大小,1080/16rem,就可以获取到设计图对应到当前屏幕的一个比例
@rem:1080/16rem;
@import 'mixin/1-px';
@import 'extend/clearfix';//清除浮动
#wrap{
height: 100%;
overflow: auto;
background-color: #EEEEEE;
.head{
position: relative;
width: 100%;
height: 270/@rem;
background-color: #232323;
.head-top{
height: 135/@rem;
.logo {
float: left;
img{
width:240/@rem;
height: 88/@rem;
padding: 26/@rem 17/@rem 21/@rem 17/@rem;//上右下左
}
}
.menuBtn{
float: left;
width: 129/@rem;
height: 135/@rem;
background: url(../img/menuBtn.png) no-repeat;
background-size: 82/@rem 233/@rem;
background-position: center 16/@rem;
&.active{
background-position: center -120/@rem;
}
}
.buttons{
float: right;
padding-top:21/@rem;
a{
float: left;
width: 111/@rem;
height: 78/@rem;
line-height: 78/@rem;
background-color: #690;
color: #ccc;
margin-right: 15/@rem;
font-size: 42/@rem;
text-align: center;
border-radius: 8/@rem;
&.search{
width: 130/@rem;
height: 88/@rem;
color: #fff;
margin-right: 30/@rem;
margin-top: 3/@rem;
font-weight: bold;
border-radius:10/@rem;
}
}
}
}
.head-bottom{
height: 103/@rem;
padding: 16/@rem;
.search{
input[type="text"]{
box-sizing: border-box;
width: 829/@rem;
height: 103/@rem;
background-color: #999;
padding: 5/@rem 10/@rem;
border:1px solid #5a5a5a;
font-size: 41/@rem;
color: #333;
border-radius: 15/@rem 0 0 15/@rem;
}
input[type="button"]{
box-sizing: border-box;
width: 190/@rem;
height: 103/@rem;
background-color: #414040;
font-size: 41/@rem;
color: #fff;
border-radius: 15/@rem;
}
}
}
.mask{
.1-px(top,#6a6a6a);
position: absolute;
z-index: 2;
top: 135/@rem;
width: 100%;
padding: 10/@rem 0;
display: none;
background-color: rgba(0,0,0,0.8);
> li{
float: left;
width: 22.5%;
height: 135/@rem;
line-height: 135/@rem;
font-size: 54/@rem;
text-align: center;
> a{
color: white;
}
}
}
}
.content{
overflow-x:hidden ;
overflow-y: scroll;
// background: pink;
position: absolute;
top: 270/@rem;
bottom: 0;
left: 0;
right: 0;
.nav{
.1-px(bottom);
width: 100%;
height: 177/@rem;
box-sizing: border-box;
background: #EEEEEE;
padding: 31/@rem 0 14/@rem 0;
.list{
position: absolute;
font-size: 0;
white-space: nowrap;/* 重点,让宽度不一样的元素排成一行规范,让元素不换行 */
float: left;/* 重点,让宽度不一样的元素排成一行规范,浮动起来才能让容器被不换行的元素撑开 */
> li{
display: inline-block;/* 重点,让宽度不一样元素排成一行,float不能用,容器宽度不够会自动换行 */
height: 129/@rem;
line-height: 129/@rem;
padding: 0 38/@rem;
font-size: 1rem;
a{
color: #020202;
}
&.active{
background: #690;
a{
color: #fff;
}
}
}
}
}
.tap_wrap{
width: 1046/@rem;
background: #FFFFFF;
overflow: hidden;
margin: 0 auto;
.tap_head{
height: 135/@rem;
line-height: 135/@rem;
h2{
float: left;
font-size: 1rem;
}
span{
float: right;
font-size: 0.7rem;
}
}
.tap_nav{
position: relative;
height: 105/@rem;
line-height: 105/@rem;
a{
float: left;
height: 105/@rem;
width: 120/@rem;
font-size: 44/@rem;
text-align: center;
color: #6b6b6b;
}
.smallG{
position: absolute;
left: 0;
bottom: 10/@rem;
width:120/@rem;
height:9/@rem;
background: #6f900d;
}
}
.tap_content{
&:extend(.clearfix all);
width: 300%;
position: relative;
ul{
float: left;
&:extend(.clearfix all);//使用继承样式
width: 33.3333333%;
li{
box-sizing: border-box;
float: left;
width: 506/@rem;
margin: 8/@rem;
padding: 5/@rem;
font-size: 40/@rem;
background-color: #efefef;
color: #000;
overflow: hidden;
a{
img{
width: 100%;
}
span{
display: block;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
}
.tap_discuss{
.right{
float: left;
margin-right: 30/@rem;
vertical-align: middle;
span:nth-child(1){
vertical-align: middle;
display: inline-block;
height: .6rem;
width: .8rem;
background: url(../img/ice.png) no-repeat;
margin-right: 5/@rem;
}
}
.left{
float: left;
vertical-align: middle;
span:nth-child(1){
vertical-align: middle;
display: inline-block;
width: .8rem;
height: .6rem;
background: url(../img/ice.png) no-repeat;
background-position:0rem -60/@rem;
margin-right: 5/@rem;
}
}
}
}
}
.tap_loding{
background: url(../img/loading.gif) no-repeat;
height: 10rem;
background-position: center;
}
}
}
}
}
7、页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<link rel="stylesheet" type="text/css" href="assets/css/index.css"/>
<link rel="stylesheet" type="text/css" href="assets/css/carouse/carouse.css"/>
</head>
<body>
<div id="wrap">
<div class="head"><!-- 头部组件 -->
<div class="head-top"><!-- 头部组件的上面部分 -->
<h1 class="logo"><!-- logo -->
<a href="javascript:;">
<img src="assets/img/logo.png" >
</a>
</h1>
<a href="javascript:;" class="menuBtn"><!-- 面包屑导航 -->
</a>
<div class="buttons">
<a href="javascript:;" class="search">搜索</a>
<a href="javascript:;">登陆</a>
<a href="javascript:;">注册</a>
</div>
</div>
<div class="head-bottom"><!-- 头部组件下面的导航部分 -->
<div class="search">
<input type="text" placeholder="点我" />
<input type="button" value="搜索" />
</div>
</div>
<ul class="mask">
<li>
<a href="javascript:;">首页</a>
</li>
<li>
<a href="javascript:;">MV</a>
</li>
<li>
<a href="javascript:;">约旦</a>
</li>
<li>
<a href="javascript:;">v榜</a>
</li>
<li>
<a href="javascript:;">音乐</a>
</li>
<li>
<a href="javascript:;">商城</a>
</li>
<li>
<a href="javascript:;">节目</a>
</li>
<li>
<a href="javascript:;">饭团</a>
</li>
<li>
<a href="javascript:;">咨询</a>
</li>
<li>
<a href="javascript:;">我的家</a>
</li>
<li>
<a href="javascript:;">APP下载</a>
</li>
<li>
<a href="javascript:;">热门引用</a>
</li>
</ul>
</div>
<div class="content">
<div class="nav">
<ul class="list txt">
<li class="active">
<a href="javascript:;">首页</a>
</li>
<li>
<a href="javascript:;">MV</a>
</li>
<li>
<a href="javascript:;">约旦</a>
</li>
<li>
<a href="javascript:;">v榜</a>
</li>
<li>
<a href="javascript:;">音乐</a>
</li>
<li>
<a href="javascript:;">商城</a>
</li>
<li>
<a href="javascript:;">节目</a>
</li>
<li>
<a href="javascript:;">饭团</a>
</li>
<li>
<a href="javascript:;">咨询</a>
</li>
<li>
<a href="javascript:;">我的家</a>
</li>
<li>
<a href="javascript:;">APP下载</a>
</li>
<li>
<a href="javascript:;">热门引用</a>
</li>
</ul>
</div>
<div class="carouse_wrap" needCarouse needAutoCarouse ><!-- 轮播容器 -->
</div>
<div class="tap_wrap"><!-- tap选项卡 -->
<div class="tap_head"><!-- tap头信息 -->
<h2>MV主播</h2>
<span>更多></span>
</div>
<div class="tap_nav"><!-- tap导航 -->
<a href="javascript:;">全部</a>
<a href="javascript:;">内地</a>
<a href="javascript:;">港台</a>
<a href="javascript:;">欧美</a>
<a href="javascript:;">韩国</a>
<a href="javascript:;">日本</a>
<span class="smallG"></span>
</div>
<div class="tap_content"><!-- tap内容 -->
<ul class="tap_loding"></ul>
<ul>
<li>
<a href="javascript:;">
<img src="assets/img/a.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/b.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/c.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/d.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/e.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/f.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
</ul>
<ul class="tap_loding"></ul>
</div>
</div>
<div class="tap_wrap"><!-- tap选项卡 -->
<div class="tap_head"><!-- tap头信息 -->
<h2>MV主播</h2>
<span>更多></span>
</div>
<div class="tap_nav"><!-- tap导航 -->
<a href="javascript:;">全部</a>
<a href="javascript:;">内地</a>
<a href="javascript:;">港台</a>
<a href="javascript:;">欧美</a>
<a href="javascript:;">韩国</a>
<a href="javascript:;">日本</a>
<span class="smallG"></span>
</div>
<div class="tap_content"><!-- tap内容 -->
<ul class="tap_loding"></ul>
<ul>
<li>
<a href="javascript:;">
<img src="assets/img/a.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/b.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/c.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/d.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/e.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
<li>
<a href="javascript:;">
<img src="assets/img/f.jpg" />
<span>安联大厦块级父垃圾广告士大夫</span>
</a>
<div class="tap_discuss">
<div class="right">
<span></span>
<span>2000</span>
</div>
<div class="left">
<span></span>
<span>6</span>
</div>
</div>
</li>
</ul>
<ul class="tap_loding"></ul>
</div>
</div>
</div>
</div>
</body>
<script src="assets/js/tools.js" type="text/javascript" charset="utf-8"></script><!-- 操作ClassName -->
<script src="assets/js/Carouse.js" type="text/javascript" charset="utf-8"></script><!-- 无缝滑屏轮播 -->
<script type="text/javascript">
window.onload=function(){
/* 全局禁用默认事件 */
document.addEventListener("touchstart",function(ev){
ev = ev||event;
ev.preventDefault();
});
/* 无缝轮播 */
carouse.initCarouse(["assets/img/1.jpg","assets/img/2.jpg","assets/img/3.jpg","assets/img/4.jpg","assets/img/5.jpg"]);
/* 获取适配 */
(function(){
let style = document.createElement("style");//创建style结点
let width = document.documentElement.clientWidth/16;//让widht为视口的16分之一
style.innerHTML="html{font-size:"+width+"px !important}";//设置根标签字体大小
document.head.appendChild(style);//将其添加到head
})();
/* ===================遮罩js=================== */
let mask = document.querySelector("#wrap .head .mask");
let menuBtn = document.querySelector("#wrap .head .head-top .menuBtn");
let flag = false;//用来标识遮罩按钮的状态
CMCFMenuBtn();
function CMCFMenuBtn(){
menuBtn.addEventListener("touchstart",function(ev){
ev= ev||event;
flag = !flag;
if(flag){
tools.addClass(menuBtn,"active")//给menuBtn的className+上一个active
mask.style.display="block";//菜单显示
}else{
tools.removeClass(menuBtn,"active");//移除active
mask.style.display="none";//菜单隐藏
}
ev.stopPropagation(); //取消事件冒泡,避免点击menuBtn触发touchstart事件的时候,
//触发下面document的touchstart事件
ev.preventDefault();//记住每次阻止冒泡要重新禁用默认事件,因为全局的阻止默认事件,被阻止冒泡了
})
mask.addEventListener("touchstart",function(ev){
ev = ev||event;
ev.stopPropagation();/* 取消事件冒泡,避免点击遮罩的时候触发下面document的事件 */
ev.preventDefault();
})
document.addEventListener("touchstart",function(ev){
ev = ev||event;
if(flag){
mask.style.display="none";//菜单隐藏
flag=!flag;
tools.removeClass(menuBtn,"active");//移除active
}
})
}
/* ==================表单js======================= */
/* 实现点击文本框,让手机弹出输入法 */
changeFocus();
function changeFocus(){
let inputText = document.querySelector("#wrap .head .head-bottom .search input[type='text']");
inputText.addEventListener("touchstart",function(ev){
ev= ev||event;
inputText.focus();//让文本框获取焦点,输入法会弹出来
ev.stopPropagation();//不要让事件穿透
ev.preventDefault();
})
/* 点击空白区,让输入法收回 */
document.addEventListener("touchstart",function(){
inputText.blur();//移除当前元素所获得的键盘焦点
})
}
/* =====================拖动导航js======================= */
dragNav();
function dragNav(){
//滑屏区域
let navArea = document.querySelector("#wrap .content .nav");
//滑屏元素
let nav_list = document.querySelector("#wrap .content .nav .list");
let startX = 0; //手指按下的位置
let endX = 0; //手指移开的位置
let moveX = 0; //手指移动的距离
let ElStartX = 0; //元素一开始的位置
let transformX = 0; //元素跟随手指移动的距离
//元素最后的位置,用滑屏区域-滑屏元素
let ElEndX = navArea.clientWidth-nav_list.offsetWidth;
/* 快速滑屏需要的参数,实现用户突然加速滑动的良好体验
通过判断用户是否在短时间内滑动一定量的距离,如果符合,进行快速滑屏
*/
let lastTime = 0; //上次点击的时间
let nowTime = 0; //现在的时间
let lastPoint = 0; //上次手指位置(不是上次滑屏位置)
let nowPoint = 0; //现在位置
let differenceTime = 0;//上次点击时间与当前时间的差
let differencePoint = 0;//手指上次位置与当前位置的差
navArea.addEventListener("touchstart",function(ev){
ev = ev||event;
let touchC=ev.changedTouches[0];
nav_list.style.transition="none";//每次点击时清除动画
startX = touchC.clientX; //获取手指初始位置
ElStartX = nav_list.offsetLeft; //获取元素初始位置
/* 快速滑屏 */
lastTime = new Date().getTime();//设置上传点击时间为当前时间
lastPoint = startX; //设置上次点击位置为当前位置
differencePoint = 0;
})
navArea.addEventListener("touchmove",function(ev){
ev = ev||event;
let touchC = ev.changedTouches[0];
let nowX = touchC.clientX; //获取当前手指位置
moveX = nowX-startX; //获取移动距离
transformX = ElStartX + moveX; //元素跟随手指移动距离
/* 橡皮筋效果 */
if(nav_list.offsetLeft>=0){//如果要小于元素最后的位置,就不要让元素继续走,有橡皮筋效果
/* scale用来保存一个比例,实现我越滑,比例越小,移动距离越短,越难滑的效果
document.documentElement.clientWidth为视口宽度
transformX是手指滑动距离 两个值加起来就会越来越大
clientWidth/(clientWidth+transformX)这个比例就会越来越小,如果给(clientWidth+transformX)*2就更小了
这时让元素移动的距离*这个比例,就会越滑,移动距离越短
*/
let scale = document.documentElement.clientWidth/((document.documentElement.clientWidth+transformX)*2);
transformX = ElStartX + moveX*scale;
}else if(nav_list.offsetLeft<=ElEndX){//大于0就不要让其往前滑屏,有橡皮筋效果
let scale = document.documentElement.clientWidth/(document.documentElement.clientWidth+transformX);
transformX = ElStartX - moveX*scale;
}
//让元素跟随手指移动
nav_list.style.left=transformX+'px';
/* 快速滑屏 */
nowTime = new Date().getTime(); //设置当前时间
nowPoint = nowX; //设置当前位置
differencePoint = nowPoint - lastPoint;
differenceTime = nowTime - lastTime;
lastPoint = nowPoint;
lastTime = nowTime;
})
navArea.addEventListener("touchend",function(ev){
ev=ev||event;
/* 快速滑屏 */
let speed = differencePoint/differenceTime;//距离/时间=速度
let targetX = transformX + speed*differencePoint; //快速滑屏偏移,让当前偏移+速度的50倍
let time = Math.abs(speed)*0.2; //保存时间,用于设置动画的时间
time = time<1?1:time; //让时间不能少于1
if(Math.abs(speed)<0.1){//如果速度小于1
time = 0; //让time=0,轻轻滑动不需要动画
targetX = transformX; //targetX无需加快速滑屏偏移
}
let bsr="";//保存贝塞尔曲线
/* 橡皮筋效果 */
if(nav_list.offsetLeft>0 || differencePoint>10 ){//如果当前元素偏移>0,或者距离差>10
targetX = 0;//让targetX=0
bsr="cubic-bezier(.01,1.36,.46,1.46)";//设置一个贝塞尔曲线
}else if(nav_list.offsetLeft <= ElEndX ||differencePoint<-10 ){//如果当前元素偏移<元素最后位置,或者距离差<-10
targetX = ElEndX;//让偏移位置为最后位置
bsr="cubic-bezier(.01,1.36,.46,1.46)";//设置贝塞尔曲线
}
nav_list.style.transition=time+"s "+bsr+" left";//放开一瞬间给贝塞尔曲线动画效果
if(differencePoint!=0){/* 如果=0表示只是点击没有移动,不需要偏移 */
nav_list.style.left=targetX+'px';//偏移targetX
}
})
}
/* ======================tap选项卡js===================== */
tap();
function tap(){
let tap_wrap = document.querySelector("#wrap .content .tap_wrap");
let tap_content_ul_all = document.querySelectorAll("#wrap .content .tap_wrap .tap_content");
let tap_content_smallG_all = document.querySelectorAll("#wrap .content .tap_wrap .tap_nav .smallG");
let arr=tap_wrap.querySelectorAll("#wrap .content .tap_wrap .tap_nav > a");//获取选项卡下所有导航
for(let i = 0;i < tap_content_ul_all.length;i++){
move(tap_content_ul_all[i],tap_content_smallG_all[i],arr.length);//给每个选项卡和对应小绿条添加移动逻辑
}
function move(content,smallG,length){
content.style.left = -tap_wrap.offsetWidth+"px";//默认偏移
let start = {x:0,y:0};//初始手指位置
let ElStart = {x:0,y:0};//元素初始位置
let xOrY = true; //true表示为X轴滑动
let first = true; //判断用户是否第一次滑,true表示第一次
let stop = false; //决定用户当前能否触发事件
let isFlag = true; //判断用户是否划过2分之一
smallG.index=0; //初始化小绿下标
content.addEventListener("touchstart",function(ev){
ev = ev||event;
xOrY = true;
isFlag = true;
if(stop){return;}
touchC = ev.changedTouches[0];
start.x = touchC.clientX;
start.y = touchC.clientY;
ElStart.x = content.offsetLeft;
ElStart.y = content.offsetTop;
stop = false;
content.style.transition = "none";//清除动画效果
})
content.addEventListener("touchmove",function(ev){
ev = ev||event;
if(stop){return;}
/* 防抖1,如果首次滑为y轴,不执行滑屏逻辑 */
if(!xOrY){
return;
}
touchC = ev.changedTouches[0];
let now = {x:0,y:0};
now.x = touchC.clientX;
now.y = touchC.clientY;
let difference = {x:now.x - start.x,y:now.y - start.y}//距离
/* 防抖2,如果是首次就判断是滑的哪个轴 */
if(first){
first = false;//变为false表示不再是第一次滑
if(Math.abs(difference.x) < Math.abs(difference.y)){//如果x的差<y的差,表示y轴滑
xOrY = false;//false表示y轴
return;//直接终止本次
}
}
if(Math.abs(difference.x) >= tap_wrap.offsetWidth*1/3){//如果移屏超过2分之一就偏移到过渡动画
let left = difference.x<0?-2:0;//如果difference.x<0表示左滑>0表示右滑
content.style.transition = "1s left";
content.style.left = left*tap_wrap.offsetWidth+"px";
isFlag = false;//进入2分之一
/* 过渡动画执行完毕,发送请求 */
stop = true;//阻止用户的触屏事件逻辑
content.addEventListener("transitionend",endFn);
content.addEventListener("webkitTransitionEnd",endFn);
/* 小绿条 */
smallGMove(left);
}else{
content.style.left = ElStart.x + difference.x +"px";
}
})
/* 小绿条移动 */
function smallGMove(left){
smallG.style.transition = "1s left";
smallG.lastIndex = smallG.index;//记录当前索引
if(left === 0 ){//等于0表示右滑
if(smallG.index === 0){//如果等于0,就让小绿条去最后面
smallG.index = length-1;
}else{//不等于0就减一
smallG.index--;
}
}else{//左滑
if(smallG.index === length-1){//小绿条在最后面就去最前面
smallG.index=0;
}else{
smallG.index++;
}
}
smallG.style.left = smallG.index*smallG.offsetWidth+"px";
}
/* 动画执行完毕后,发送请求 */
function endFn(){
/* 先解绑事件 */
content.removeEventListener("transitionend",endFn);
content.removeEventListener("webkitTransitionEnd",endFn);
let flag = "";//这个应该是全局的,代表当前请求回来的数据
let timer = setTimeout(function(){
flag = "";/* 将你请求回来的数据替换 ,因为没有后端,就假装模拟一下*/
if(Math.floor((Math.random()*3+1))===2){//有3分之1几率请求失败
content.style.left = -1*tap_wrap.offsetWidth+"px";
alert("请求失败");
/* 小绿条回到上次位置 */
smallG.index= smallG.lastIndex;
smallG.style.left = smallG.index*smallG.offsetWidth+"px";
stop = false;
}else{//请求成功
content.style.transition = "none";
content.style.left = -1*tap_wrap.offsetWidth+"px";
stop = false;
}
clearTimeout(timer)
},100)
}
content.addEventListener("touchend",function(ev){
ev = ev||event;
if(stop){return;}
touchC = ev.changedTouches[0];
if(isFlag){//如果是true表示还得回到当前屏
content.style.transition = "2s left";
content.style.left = -tap_wrap.offsetWidth+"px";
//如果回到当前屏依然可以让用户进行下次滑屏
}else{//如果为false,表示已经滑屏成功,进入加载动画,不准继续滑屏
stop = true;
console.log(1)
}
xOrY = true;
first = true;
isFlag = true;
// stop = false;
})
}
}
}
</script>
</html>