微信里经常看到的滑动翻页效果,slide

时间:2025-05-04 16:04:25

上个星期我们的产品姐姐让我帮她写个微信里经常看到的滑动翻页效果,今天抽空写了3个小demo(只写了webkit需要chrome模拟手机看 开启touch事件), 故此写个随笔。

1、demo1,整个大容器tranlateY(性能应该是最好的,但是如果增删一页的话对css影响很大,如果用sass或less除外)

html:

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta name="viewport" content="width=320.1, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="./demo.css">
</head>
<body> <div class="slide_div">
<div class="slide_page_1 slide_page"></div>
<div class="slide_page_2 slide_page"></div>
<div class="slide_page_3 slide_page"></div>
<div class="slide_page_4 slide_page"></div>
</div> </body>
<script src="../zepto.js"></script>
<script src="demo.js"></script>
</html>
* {
padding:;
margin:;
} html, body {
width: 100%;
height: 100%;
overflow: hidden;
} .slide_div {
width: 100%;
height: 400%;
position: absolute;
} .slide_page {
width: 100%;
height: calc(100% / 4);
background-size: 100% 100% !important;
}
.slide_page_1 {
background: url(../img/pic1.jpg) no-repeat;
} .slide_page_2 {
background: url(../img/pic2.jpg) no-repeat;
} .slide_page_3 {
background: url(../img/pic3.jpg) no-repeat;
} .slide_page_4 {
background: url(../img/pic4.jpg) no-repeat;
} .slide_page:before {
content: '';
position: absolute;
width: 47px;
height: 47px;
margin-left: -23px;
background: url(../img/arrow.png) no-repeat center 0;
-webkit-animation: start 1.5s infinite ease-in-out;
}
.slide_page_1:before {
left: 50%;
top: calc(100% / 4 - 2.5%);
}
.slide_page_2:before {
left: 50%;
top: calc(100% / 4 * 2 - 2.5%);
}
.slide_page_3:before {
left: 50%;
top: calc(100% / 4 * 3 - 2.5%);
}
.slide_page_4:before {
content: none;
} @-webkit-keyframes start {
0%,30% {opacity:;-webkit-transform: translate(0,10px);}
60% {opacity:;-webkit-transform: translate(0,0);}
100% {opacity:;-webkit-transform: translate(0,8px);}
} /************ slide up **************/
.slide_animate_up_1 {
-webkit-animation:slide_up_1 .5s ease both;
}
.slide_animate_up_2 {
-webkit-animation:slide_up_2 .5s ease both;
}
.slide_animate_up_3 {
-webkit-animation:slide_up_3 .5s ease both;
} @-webkit-keyframes slide_up_1 {
100% {
-webkit-transform:translateY(calc(-100% / 4));
}
}
@-webkit-keyframes slide_up_2 {
0% {
-webkit-transform:translateY(calc(-100% * 1/4));
}
100% {
-webkit-transform:translateY(calc(-100% * 2/4));
}
}
@-webkit-keyframes slide_up_3 {
0% {
-webkit-transform:translateY(calc(-100% * 2/4));
}
100% {
-webkit-transform:translateY(calc(-100% * 3/4));
}
} /************ slide down **************/
.slide_animate_down_0 {
-webkit-animation:slide_down_0 .5s ease both;
}
.slide_animate_down_1 {
-webkit-animation:slide_down_1 .5s ease both;
}
.slide_animate_down_2 {
-webkit-animation:slide_down_2 .5s ease both;
} @-webkit-keyframes slide_down_0 {
0% {
-webkit-transform:translateY(calc(-100% / 4));
}
100% {
-webkit-transform:translateY(0px);
}
}
@-webkit-keyframes slide_down_1 {
0% {
-webkit-transform:translateY(calc(-100% * 2/4));
}
100% {
-webkit-transform:translateY(calc(-100% * 1/4));
}
}
@-webkit-keyframes slide_down_2 {
0% {
-webkit-transform:translateY(calc(-100% * 3/4));
}
100% {
-webkit-transform:translateY(calc(-100% * 2/4));
}
}

js:

/**
* Created by huangjianhua on 14-12-14.
*/
$(function () {
var cur_page= 0, touchFirst_obj, touchLast_obj, touchEnd_obj, moveY,
slide_range = 30,
page_count = $('.slide_div div').length || 4; $(document).on('touchstart', '.slide_div', function (e) {
e.preventDefault();
touchFirst_obj = {
startY : e.touches[0].clientY
}; }); $(document).on('touchmove', '.slide_div', function (e) {
e.preventDefault();
touchLast_obj = e.touches[0]; moveY = touchLast_obj.clientY - touchFirst_obj.startY;
}); $(document).on('touchend', '.slide_div', function (e) {
// touchEnd_obj = e.changedTouches[0]; //上 或 下
if(moveY > 0) {
//第一页的话 不作处理
if(cur_page == 0) return;
cur_page--;
$(this).attr('class', 'slide_div slide_animate_down_' + cur_page);
} else if(moveY < 0) {
//最后一页的话 return
if(cur_page == +page_count-1) return;
cur_page++;
$(this).attr('class', 'slide_div slide_animate_up_' + cur_page);
}
});
});

2、demo2,单独每页tranlateY(增删一页的话对css和js影响都不大,但是我觉得性能没demo1好)

html一样,
css:

* {
padding:;
margin:;
} html, body {
width: 100%;
height: 100%;
overflow: hidden;
} .slide_div {
width: 100%;
height: 100%; }
.hide {
display: none;
}
.current {
display: block;
} .slide_page {
width: 100%;
height: 100%;
position: absolute;
background-size: 100% 100% !important;
}
.slide_page_1 {
background: url(../img/pic1.jpg) no-repeat;
} .slide_page_2 {
background: url(../img/pic2.jpg) no-repeat;
} .slide_page_3 {
background: url(../img/pic3.jpg) no-repeat;
} .slide_page_4 {
background: url(../img/pic4.jpg) no-repeat;
}
.slide_page_5 {
background: url(../img/pic1.jpg) no-repeat;
}
.slide_page:before {
content: '';
position: absolute;
width: 47px;
height: 47px;
margin-left: -23px;
background: url(../img/arrow.png) no-repeat center 0;
-webkit-animation: start 1.5s infinite ease-in-out;
}
.slide_page_1:before {
left: 50%;
bottom:3%;
}
.slide_page_2:before {
left: 50%;
bottom:3%;
}
.slide_page_3:before {
left: 50%;
bottom:3%;
}
.slide_page_4:before {
content: none;
} @-webkit-keyframes start {
0%,30% {opacity:;-webkit-transform: translate(0,10px);}
60% {opacity:;-webkit-transform: translate(0,0);}
100% {opacity:;-webkit-transform: translate(0,8px);}
} /************ slide up **************/
.moveToTop {
-webkit-animation: toTop .5s ease both;
} .moveFromTop {
-webkit-animation: fromTop .5s ease both;
} .moveToBottom {
-webkit-animation: toBottom .5s ease both;
} .moveFromBottom {
-webkit-animation: fromBottom .5s ease both;
} @-webkit-keyframes toTop {
from { }
to { -webkit-transform: translateY(-100%); }
} @-webkit-keyframes fromTop {
from { -webkit-transform: translateY(-100%); }
} @-webkit-keyframes toBottom {
from { }
to { -webkit-transform: translateY(100%); }
} @-webkit-keyframes fromBottom {
from { -webkit-transform: translateY(100%); }
}

js:

/**
* Created by huangjianhua on 14-12-14.
*/
$(function () {
var cur_page= 0, touchFirst_obj, touchLast_obj, touchEnd_obj, moveY,
slide_range = 30,
page_count = $('.slide_div div').length || 4; $(document).on('touchstart', '.slide_page', function (e) {
e.preventDefault();
touchFirst_obj = {
startY : e.touches[0].clientY
};
}); $(document).on('touchmove', '.slide_page', function (e) {
e.preventDefault();
touchLast_obj = e.touches[0]; moveY = touchLast_obj.clientY - touchFirst_obj.startY; }); $(document).on('touchend', '.slide_page', function (e) {
// touchEnd_obj = e.changedTouches[0]; //上 或 下
if(moveY > 0) {
//第一页的话 不作处理
if(cur_page == 0) return;
cur_page--;
$(this).prev('.slide_page').removeClass('hide').addClass('moveFromTop').addClass('current');
$(this).addClass('moveToBottom'); $(this).on('webkitAnimationEnd', function() {
$(this).prev('.slide_page').removeClass('moveFromTop');
$(this).removeClass('moveToBottom').removeClass('current').addClass('hide');
$(this).off('webkitAnimationEnd');
}); } else if(moveY < 0) {
//最后一页的话 return
if(cur_page == +page_count-1) return;
cur_page++;
$(this).addClass('moveToTop').removeClass('moveFromBottom');
$(this).next('.slide_page').removeClass('hide').addClass('moveFromBottom').addClass('current');
$(this).on('webkitAnimationEnd', function() {
$(this).removeClass('moveToTop').removeClass('current').addClass('hide');
$(this).next('.slide_page').removeClass('moveFromBottom');
$(this).off('webkitAnimationEnd');
}); }
}); });

3、demo3,带吸附功能,是用transition写的(因为之前我们一个活动游戏的指南页使用jq的animate写的,然后低端机卡得一塌糊涂,这次我还特意加上了tranlateZ(0),我觉得性能怎样也比jquery的animate好).
html一样的,

css:

* {
padding:;
margin:;
} html, body {
width: 100%;
height: 100%;
overflow: hidden;
} .slide_div {
width: 100%;
height: 400%;
position: absolute;
} .slide_page {
width: 100%;
height: calc(100% / 4);
background-size: 100% 100% !important;
}
.slide_page_1 {
background: url(../img/pic1.jpg) no-repeat;
} .slide_page_2 {
background: url(../img/pic2.jpg) no-repeat;
} .slide_page_3 {
background: url(../img/pic3.jpg) no-repeat;
} .slide_page_4 {
background: url(../img/pic4.jpg) no-repeat;
} .slide_page:before {
content: '';
position: absolute;
width: 47px;
height: 47px;
margin-left: -23px;
background: url(../img/arrow.png) no-repeat center 0;
-webkit-animation: start 1.5s infinite ease-in-out;
}
.slide_page_1:before {
left: 50%;
top: calc(100% / 4 - 2.5%);
}
.slide_page_2:before {
left: 50%;
top: calc(100% / 4 * 2 - 2.5%);
}
.slide_page_3:before {
left: 50%;
top: calc(100% / 4 * 3 - 2.5%);
}
.slide_page_4:before {
content: none;
} @-webkit-keyframes start {
0%,30% {opacity:;-webkit-transform: translate(0,10px);}
60% {opacity:;-webkit-transform: translate(0,0);}
100% {opacity:;-webkit-transform: translate(0,8px);}
} /************ transition **************/
.transition_fast {
-webkit-transition: .6s ease;
}

js:

/**
* Created by huangjianhua on 14-12-14.
*/
$(function () {
var cur_page= 0, touchFirst_obj, touchLast_obj, touchEnd_obj, moveY, startTranslateY, currentTranslateY,
slide_range = 130,
page_count = $('.slide_div div').length || 4; $(document).on('touchstart', '.slide_div', function (e) {
e.preventDefault();
touchFirst_obj = {
startY : e.touches[0].clientY
}; $(this).removeClass('transition_fast'); //取translateY的值
var transfrom_info = window.getComputedStyle(e.currentTarget, null).getPropertyValue("-webkit-transform").match(/matrix\((\d+,\s?){1,5}(\-?\d+)/);
startTranslateY = transfrom_info && transfrom_info[2] || 0; $(this).css('-webkit-transform', 'translateY('+ startTranslateY +'px) translateZ(0)');
// console.log(startTranslateY , 'startY',window.getComputedStyle(e.currentTarget, null).getPropertyValue("-webkit-transform")); }); $(document).on('touchmove', '.slide_div', function (e) {
e.preventDefault();
touchLast_obj = e.touches[0]; moveY = touchLast_obj.clientY - touchFirst_obj.startY;
currentTranslateY = +startTranslateY + +moveY; //第一张往上、和最后一张往下 return;
if((startTranslateY ==0 && moveY > 0) || (startTranslateY == -window.innerHeight * (page_count-1) && moveY < 0)) {
return;
}
$(this).css('-webkit-transform', 'translateY('+ currentTranslateY +'px) translateZ(0)'); }); $(document).on('touchend', '.slide_div', function (e) {
// touchEnd_obj = e.changedTouches[0];
$(this).addClass('transition_fast');
//上 或 下
if(moveY > slide_range) {
//第一页的话 不作处理
if(cur_page == 0) return;
cur_page--;
} else if(moveY < -slide_range) {
//最后一页的话 return
if(cur_page == +page_count-1) return;
cur_page++;
} $(this).css('-webkit-transform', 'translateY('+ (-100 * (+cur_page)/4) +'%) translateZ(0)');
});
});

好了大致就是这样3个demo,括号里的都是我的废话可以忽视,上github地址(github处女项目哦):https://github.com/skyweaver213/slide

谢谢围观,说得不对的地方欢迎吐槽, ^ ^。