说在开头
最近移动端做了一个手指左右滑动切换内容的效果demo;
为了表示我的无私,决定分享给诸位;(详细代码见附件)
正文
先上html代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width = device-width" />
<title></title>
<link rel="stylesheet" type="text/css" href="main.css">
<script type="text/javascript">
</script>
</head>
<body>
<div class="j-cont">
<div class="title">穿衣助理</div>
<div class="m-shape">
<div class="cont">
<ul class="f-cb"></ul>
</div>
<div class="but_cont">
<span class="but">完成</span>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript" src="main.js"></script>
</html>
css代码如下:(这里直接贴上了less编译之后)
body,div,ul{margin: 0px;padding: 0px;}
.m-shape{box-sizing: border-box;}
.m-shape .cont{ overflow: hidden;box-sizing: border-box;
}
.j-cont{ margin: 0 auto;
width: 100%;}
.m-shape .cont ul {
width: 1000%;
position: relative;
margin: 0 7%;
overflow: hidden;
}
.m-shape .cont ul li {
display: inline-block;
float: left;
width: 8%;
padding: 0 0.3%;
overflow: hidden;
box-sizing: content-box;
}
.m-shape .cont ul li .tishi {
position: absolute;
border-radius: 50%;
background: url(../p_w_picpaths/Assist_icon.png) no-repeat;
background-size: 30px 30px;
width: 30px;
height: 30px;
right: 10px;
top: 10px;
}
.m-shape .cont ul li .title {
height: 40px;
line-height: 40px;
text-align: center;
}
.m-shape .cont ul li .cont {
height: 77%;
text-align: center;
}
.m-shape .cont ul li .cont .img {
height: 100%;
text-align: center;
}
.m-shape .cont ul li .cont .img img {
height: 100%;
min-height: 100%;
max-height: 100%;
}
.m-shape .cont ul li .cont p {
text-align: center;
line-height: 40px;
}
.m-shape .cont ul li .msg {
position: absolute;
top: 100%;
left: 10%;
background: rgba(0, 0, 0, 0.5);
color: #fff;
line-height: 30px;
padding: 10px;
width: 80%;
border-radius: 4px;
}
.m-shape .cont ul li .j-conts_item {
background: #9DE0FF;
border-radius: 6px;
position: relative;
}
.m-shape .but_cont {
text-align: center;
padding: 20px 0;
}
.m-shape .but_cont .but {
background: #e9494b;
display: inline-block;
height: 30px;
line-height: 30px;
width: 30%;
border-radius: 15px;
color: #fff;
}
.title{
text-align: center;
height: 40px;
line-height: 40px;
}
上面代码有一个地方要说明一下:
j-cont的大小为保证自适应其大小与手机屏幕一致(通过js实现,详情见后面js)
而后ul的width设置为1000%;即屏幕宽度的10倍;
li的关键css如下:
width: 8%;
padding: 0 0.3%;
overflow: hidden;
box-sizing: content-box;
所以其padding+width = 86%的j-cont,即屏幕宽度的86%;
在执行滚动时我也是词义移动86%;但是存在一问题如下:
第一张图片左边没有图片;但是必须预留这个位置,不然第一张位置这样的,后面切换也会有错位:
所以给ul设置marin:0% 7%;保证首次位置正确,后面每次切换位置也正确。
为了保证所以尺寸的智能设备自由伸缩,写了一个方法初始化容器的大小:
//初始化容器
var html_cont_initialization = function () {
//初始化容器
$(".j-cont").css({
"height": $(window).height() + "px",
"min-height": $(window).height() + "px"
});
//初始化内容容器
$(".j-conts_item").css({
"height": $(window).height() - 110 + "px",
"min-height": $(window).height() - 110 + "px",
"max-height": $(window).height() - 110 + "px"
});
}
其中110px为头部title,以及按钮所在行即:$(".title"),$(".but_cont")高度之和。
还有一段代码,用来load内容模板(这个地方,现在是假数据)
var sex_initialization = function () {
var html = "";
for (var i = 0; i < 5; i++) {
html += '<li class="f-cb j-conts">\
<div class="j-conts_item"><i class="tishi"></i>\
<div class="title">您的体型是?'+ i + '</div>\
<div class="cont">\
<div class="img"><img src="p_w_picpaths/Assist_woman_' + i + '.png" /></div>\
<p>A型</p>\
</div>\
</div></li>';
}
$(".m-shape ul").append(html);
html_cont_initialization();
}
//触屏左右切换体型效果
function switchShape() {
var startX, startY, endX, endY;
var isMove = false;//触摸:start,end操作之间是否有move
var isSwitching = false;//是否正在执行动画
var curIndex = 0;
var MaxLi = $(".m-shape ul li").length - 1;
$("body").on("touchmove", ".m-shape ul", touchMoveHandler);
$("body").on("touchstart", ".m-shape ul", touchStartHandler);
$("body").on("touchend", ".m-shape ul", touchEndHandler);
//触屏左右切换体型效果
function touchStartHandler(event) {
event.preventDefault();
var touch = event.touches[0];
startY = touch.pageY;
startX = touch.pageX;
}
function touchMoveHandler(event) {
event.preventDefault();
var touch = event.touches[0];
endX = touch.pageX;
isMove = true;
}
function touchEndHandler(event) {
event.preventDefault();
if (!isMove || isSwitching) {
return;
}
var w = 86;
var curLeft = curIndex ? -curIndex * w : 0;
var dirX = 1;//滑动方向
if (Math.abs(startX - endX) > 50) {//滑动间距大于50
if (startX - endX > 0) {
if (curIndex === MaxLi) {//当前是最后一个
return;
}
curIndex++;
} else {
if (0 === curIndex) {//当前是第一个
return;
}
dirX = -1;
curIndex--;
}
}
moveTo($(this), "left", curLeft, -curIndex * w, 43, dirX);
isMove = false;
}
//动画函数
//params:对象,css属性,开始,结束,50ms移动距离,方向1←,-1右
function moveTo($obj, objProp, start, end, spacing, direction) {
var temp = start;
isSwitching = true;
var moveTimer = setInterval(function () {
if ((1 === direction && temp - end <= 0) || (-1 === direction && temp - end >= 0)) {
clearInterval(moveTimer);
isSwitching = false;
return;
}
temp = temp - spacing * direction;
$obj.css(objProp, temp + "%");
}, 200);
}
}
switchShape();
每次滑动应包括三个动作touch start,move,end缺一不可;因为触屏点击也会触发start,end;
新增isMove状态,每次move为true;end后为false;保证三个动作都触发才执行滑动。
具体滑动的距离,一般来讲30-50直接都可以;
如果当前正在执行动画,那么在此滑动时,其实应该忽略;即滑动动画执行完毕后,再执行下一次。
说在最后
本人移动端玩的少,所以考虑难免不周,多多指教!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。