要求:当内容向左右滑动时,顶部随着内容区域一同滑动,左边不动。当内向上下互动时,左侧随着内容区域一同滑动,顶部不动。
最初的思想:最初是想要进行固定定位和绝对定位的切换来达到上下左右滑动互不影响。但用该方法实现会有抖动。原因:当开始触摸屏幕时且滑动时才知道向左右滑动还是上下滑动,只有在知道了滑动方向后才可以切换固定定位和绝对定位。在未切换前,顶部/左侧会保持原来的定位方式跟着内容区域一同滑动。当切换后,才会固定/滑动。由于这种方式的先后顺序是无法改变的,故抖动也是无法避免的。
新思想:无论页面的触摸位置是否有误差,都同时设置内容区和顶部/内容区和左侧的
left
/top
,这样就会保持内容区和顶部、内容区和左侧同步滑动。在滑动前先判断用户的滑动方向,若是上下方向则只需让内容区和左侧同步滑动。若是左右方向则只需内容和顶部同步滑动。由于手触摸屏幕会有误差,故有时对上下和左右方向的判断有误。但是即便判断有误,也不会出现抖动的情况。且内容区与左侧、内容区与顶部都会同步滑动。而不会出来一方滑动,另一方延迟滑动的现象。
判断滑动方向
思想:在触摸刚开始时记录触摸位置,在触摸移动中时也同时记录触摸位置。在滑动前,对竖直方向和水平方向的开始和滑动位置的距离差进行对比,谁的绝对值大代表向哪个方向滑动
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width:device-width,initial-scale=1.0,user-scalable=no">
<title>Title</title>
</head>
<style>
*{
margin:0;
padding:0
}
body{
overflow: hidden;
}
.opt{
position: fixed;
width:70px;
height: 50px;
background: #2529ff;
color:white;
text-align: center;
line-height: 50px;
z-index: 10;
}
.title{
width: 1000px;
height: 50px;
position: absolute;
left:70px
}
.title>span{
float: left;
display: inline-block;
width: 100px;
height: 50px;
background: #c393ff;
text-align:center;
line-height: 50px;
color:white;
}
.left{
position: absolute;
height: 1000px;
width: 70px;
top:50px;
z-index: -1;
}
.left>ul{
height: 1000px;
display:flex;
flex-direction: column;
}
.left>ul>li{
flex:1;
text-align:center;
line-height: 100px;
background: #d2d394;
color:white
}
.map{
width: 1000px;
height: 1000px;
background: #ffecea;
position: absolute;
left:70px;
top:50px;
z-index: -2;
}
.content{
font-size: 0;
}
.content>div{
display: inline-block;
width: 100px;
height: 50px;
text-align: center;
line-height: 50px;
background: #d2d394;
font-size: 20px;
}
</style>
<body>
<div class="opt">
功能
</div>
<div class="title">
<span>第一栏</span>
<span>第二栏</span>
<span>第三栏</span>
<span>第四栏</span>
<span>第五栏</span>
<span>第六栏</span>
<span>第七栏</span>
<span>第八栏</span>
<span>第九栏</span>
<span>第九栏</span>
</div>
<div class="left">
<ul>
<li>第一栏</li>
<li>第二栏</li>
<li>第三栏</li>
<li>第四栏</li>
<li>第五栏</li>
<li>第六栏</li>
<li>第七栏</li>
<li>第八栏</li>
<li>第九栏</li>
<li>第十栏</li>
</ul>
</div>
<div class="map">
<div class="content">
<div>第一天</div>
<div>第二天</div>
<div>第三天</div>
<div>第四天</div>
<div>第五天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
<div>第六天</div>
</div>
</div>
<script src="js/jquery-3.0.0.js"></script>
<script src="js/jquery-1.9.1.js"></script>
<script>
var mapLeft = $(".map").css("left");
var mapTop = $(".map").css("top");
var startX = 0;
var startY = 0;
var moveX=0;
var moveY = 0;
var screenW;
var screenH;
$(function () {
screenW = $(window).width();
screenH = $(window).height();
$(".map").on("touchstart touchmove touchend",function (e) {
console.log(screenH)
if(e.type=="touchmove"){
moveX=e.originalEvent.changedTouches[0].pageX;
moveY = e.originalEvent.changedTouches[0].pageY;
var offsetX = moveX - startX;
var offsetY = moveY - startY;
if(Math.abs(offsetX)>Math.abs(offsetY)){
if(parseInt(mapLeft)+(moveX-startX)>=70 && (moveX-startX>0)){
$(".title").css("left",70);
$(this).css("left",70);
}else if(Math.abs(parseInt(mapLeft)+(moveX-startX))>=$(this).width()-screenW && (moveX-startX)<0){
$(".title").css("left",screenW-$(this).width());
$(this).css("left",screenW-$(this).width());
}
else{
$(".title").css("left",parseInt(mapLeft)+(moveX-startX));
$(this).css("left",parseInt(mapLeft)+(moveX-startX));
}
}else{
if(parseInt(mapTop)+(moveY-startY)>=50 && (moveY-startY>0)){
$(".left").css("top",50);
$(this).css("top",50);
}else if(Math.abs(parseInt(mapTop)+(moveY-startY))>=$(this).height()-screenH && (moveY-startY)<0){
$(".left").css("top",screenH-$(this).height());
$(this).css("top",screenH-$(this).height());
}
else{
$(".left").css("top",parseInt(mapTop)+(moveY-startY));
$(this).css("top",parseInt(mapTop)+(moveY-startY));
}
}
}else{
startX = e.originalEvent.changedTouches[0].pageX;
startY = e.originalEvent.changedTouches[0].pageY;
if(e.type=="touchend"){
mapLeft = $(this).css("left");
mapTop = $(this).css("top");
}
}
})
})
</script>
</body>
</html>