简单记录一下基本方法
功能:顶部导航栏可以点击跳转页面,也可以左右滑动跳转页面,当滑动的距离不够时会返回上一页,并带有动画效果
顶部导航就不用多说了
直接记录下内容区域的左右滑动是怎么实现的
原理就是通过touchstart,touchmove,touchend 三个事件实现
刚开始先确定几个全局变量
//获取每个页面的宽度
var contentLiWidth= $(".content ul li").width()
//记录第一次触屏位置
var startPoint=null
//移动的距离大于d才能下一页
var d=150
//记录内容盒子距离左边的距离
var ulLeft= $('.content ul').position().left
//手指滑动的距离
var moveX=0
touchstart
手指开始触摸屏幕时触发,通过e.originalEvent.targetTouches[0],可以获取刚开始触摸时在页面的位置,通过一个全局变量startPoint接收一下,startPoint=e.originalEvent.targetTouches[0]
touchmove
手指接触屏幕后,在屏幕上移动会不断触发该事件,通过e.originalEvent.targetTouches[0],可以不断获取手指在屏幕的距离,在该事件主要获取在x轴左右移动的距离,
该距离为 刚开始接触的位置-手指移动到的距离
moveX=startPoint.clientX-e.originalEvent.targetTouches[0].clientX
touchend
手指离开屏幕时,会触发该事件,左滑(下一页)时moveX的值肯定是大于0的,还要通过判断moveX判断是否大于d,所以分为两种情况0<moveX<d 和 move>d,0<moveX<d滑动的距离不够时是不会跳转页面的,还要判断是否滑到了最后一页。
//左滑
if(moveX<d && moveX>0){
$(".content ul").animate({
left:-contentLiWidth*index
},200, assignVal())
topList($(".top_list li").eq(index))
}else if(moveX>d){
//到最后一栏后不能滑动
if(index==$('.top_list li').length-1){
$(".content ul").animate({
left:-contentLiWidth*index
},200,assignVal())
topList($(".top_list li").eq(index))
moveX=0
return false
}
$(".content ul").animate({
left:-contentLiWidth*(index+1)
},200,assignVal())
topList($(".top_list li").eq(index+1))
}
右滑(上一页)时moveX的值小于0,也需要分为两种情况,moveX<0&&moveX>-d 和moveX<-d,
moveX<0&&moveX>-d滑动的距离不够时不会跳转页面,还要判断是否为第一页。
//右滑
if(moveX<0&&moveX>-d){
$(".content ul").animate({
left:-contentLiWidth*index
},200,assignVal())
topList($(".top_list li").eq(index))
}else if(moveX<-d){
//判断是否为第一页
if(index!=0){
$(".content ul").animate({
left:-contentLiWidth*(index-1)
},200,assignVal())
}else{
$(".content ul").animate({
left:0
},200,assignVal())
topList($(".top_list li").eq(index))
moveX=0
return false
}
topList($(".top_list li").eq(index-1))
}
判断完后一定要将moveX赋值为0
$(".content").on("touchmove",function(e){
var e=e||window.event
moveX=startPoint.clientX-e.originalEvent.targetTouches[0].clientX
$(this).find("ul").css("left",ulLeft-moveX)
})
因为ulLeft的值需要重新赋值,如果滑动过快,动画加载还没完成,会使ulLeft的值还没赋完,就再次调用,此时moveX的值会越来越大,将moveX赋值为0可以解决快速滑动的问题,当然,实际应用中会有加载页面的时间,这个问题可以不用考虑。
基本思路就这些,全部代码如下
body{
position: fixed;
top: 0;
height: 100%;
width: 100%;
}
.top{
width: 15rem;
position: relative;
}
.top_list{
background-color: #FFF;
padding: 0 0.6rem;
}
.top_list::after{
content: '';
display: block;
clear: both;
}
.top_list li{
display: inline-block;
margin-right: 0.9rem;
height: 1.5rem;
line-height: 1.5rem;
text-align: center;
}
.top_list .select_top_list{
color: red;
}
.top span{
display: block;
height: 0.08rem;
background-color: red;
border-radius: 0.04rem;
position: absolute;
bottom: 0;
}
.content{
overflow: hidden;
position: absolute;
width: 100%;
height: 100%;
}
.content ul{
display: flex;
position: absolute;
left: 0;
}
.content ul li{
overflow: scroll !important;
width: 15rem;
}
<div class="top pr">
<ul class="top_list">
<li class="select_top_list">标题一</li>
<li>标题二</li>
<li>标题三</li>
<li>标题四</li>
</ul>
<span id="bottom_line"></span>
</div>
<div class="content">
<ul>
<li>111111111111111111111111111111</li>
<li>222222222222222222222222222222222</li>
<li>333333333333333333333333333333333</li>
<li>444444444444444444444444444444444</li>
</ul>
</div>
$(document).ready(function(){
var ulLeft= $('.content ul').position().left
$(".content ul li").height($("body").height()-$(".top").height())
//获取每个页面的宽度
var contentLiWidth= $(".content ul li").width()
//给下划线赋值
$("#bottom_line").width($(".select_top_list").width()).css("left",$(".select_top_list").position().left)
//顶部导航栏点击
$(".top_list li").on("click",function(e){
event.stopPropagation()
var that=this
topList(that)
$(".content ul").animate({
left:-contentLiWidth*$(that).index()
},300,assignVal())
})
//记录第一次触屏位置
var startPoint=null
//移动的距离大于d才能下一页
var d=150
//拖动
var moveX=0
//接触开始
$(".content").on("touchstart",function(e){
var e=e||window.event
startPoint=e.originalEvent.targetTouches[0]
})
$(".content").on("touchmove",function(e){
var e=e||window.event
moveX=startPoint.clientX-e.originalEvent.targetTouches[0].clientX
$(this).find("ul").css("left",ulLeft-moveX)
})
//接触结束
$(".content").on("touchend",function(){
console.log(moveX);
var index= $(".select_top_list").index()
//左滑
if(moveX<d && moveX>0){
$(".content ul").animate({
left:-contentLiWidth*index
},200, assignVal())
topList($(".top_list li").eq(index))
}else if(moveX>d){
//到最后一栏后不能滑动
if(index==$('.top_list li').length-1){
$(".content ul").animate({
left:-contentLiWidth*index
},200,assignVal())
topList($(".top_list li").eq(index))
moveX=0
return false
}
$(".content ul").animate({
left:-contentLiWidth*(index+1)
},200,assignVal())
topList($(".top_list li").eq(index+1))
}
//右滑
if(moveX<0&&moveX>-d){
$(".content ul").animate({
left:-contentLiWidth*index
},200,assignVal())
topList($(".top_list li").eq(index))
}else if(moveX<-d){
if(index!=0){
$(".content ul").animate({
left:-contentLiWidth*(index-1)
},200,assignVal())
}else{
$(".content ul").animate({
left:0
},200,assignVal())
topList($(".top_list li").eq(index))
moveX=0
return false
}
topList($(".top_list li").eq(index-1))
}
moveX=0
})
//处理顶部下划线
function topList(obj){
$("#bottom_line").animate({
width:$(obj).width(),
left:$(obj).position().left
},300,function(){
$(obj).addClass("select_top_list").siblings().removeClass("select_top_list")
})
}
function assignVal(){
ulLeft=$('.content ul').position().left
}
})