上個星期我們的產品姐姐讓我幫她寫個微信里經常看到的滑動翻頁效果,今天抽空寫了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: 0; margin: 0; } 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: 0;-webkit-transform: translate(0,10px);} 60% {opacity: 1;-webkit-transform: translate(0,0);} 100% {opacity: 0;-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: 0; margin: 0; } 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: 0;-webkit-transform: translate(0,10px);} 60% {opacity: 1;-webkit-transform: translate(0,0);} 100% {opacity: 0;-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: 0; margin: 0; } 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: 0;-webkit-transform: translate(0,10px);} 60% {opacity: 1;-webkit-transform: translate(0,0);} 100% {opacity: 0;-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
謝謝圍觀,說得不對的地方歡迎吐槽, ^ ^。