今天閑得蛋疼,重構了之前寫的微信翻頁效果。
先上地址,覺得可以給顆星星,覺得有問題請大力吐槽。
github:
https://github.com/skyweaver213/slide
3個demo地址:
http://skyweaver213.github.io/slide/widget/slide1/slide.html
http://skyweaver213.github.io/slide/widget/slide2/slide.html
http://skyweaver213.github.io/slide/widget/slide3/slide.html
下面說的東西沒啥深度,高手到這里止步哈。 if(codeMaster) return;
然后說說我重構的思路,每次說到重構2字我都手心冒汗,我寫的破東西也敢稱得上重構?勉強說,再改了一下。
我一開始封裝的方法很挫的,就是隨便傳幾個參數

3個demo地址:



下面說的東西沒啥深度,高手到這里止步哈。 if(codeMaster) return;
然后說說我重構的思路,每次說到重構2字我都手心冒汗,我寫的破東西也敢稱得上重構?勉強說,再改了一下。
我一開始封裝的方法很挫的,就是隨便傳幾個參數
/* param1 滑動頁面的class或者 id ------------- (必傳) param2 一共幾個滑動的頁面 ------------- (必傳) param3 吸附翻頁的范圍 ------------- (不必傳) param4 滑動頁面委托事件的父節點,不傳默認是document */ function slide(slide_page_dom, page_count, slide_range, parent_wrap) { //code }
這樣我覺得有一點很不好的地方,就是別人一定要記住參數的順序,還有是否必傳 ,還有如果后續參數擴展更多的話,還可能需要判斷參數的類型再作操作,例如添加一個callback函數,還要先檢查一下是不是函數才能執行。
還有如果touchstart、touchmove和touchend同時都用callback的時候,就亂得一團糟了。
所以今天我把所有參數都當作一個對象,然后跟他們分別指定特定的名字。
例如:
/** * Created by huangjianhua on 14-12-20. */ /* param1 所有用到參數的obj { slide_page_wrap //滑動區域的class或者 id, 必傳 slide_page_dom //滑動頁面的class或者 id, 必傳 page_count //一共滑動的頁面的總個數 不必傳(不傳默認是page_dom.length) slide_range //觸發翻頁效果移動的步長 不必傳 } startCallback: function, //touchStart的回調函數 不必傳 moveCallback: function, //touchmove的回調函數 不必傳 endCallback: function //touchend的回調函數 不必傳 */ function slide(options) { //默認的值 var defaultObj = { cur_page: 0, slide_range: 130, parent_wrap: document }; //自定義的參數 $.extend(defaultObj, options); //滑動區域的class或id var slide_page_wrap = defaultObj.slide_page_wrap; //滑動頁面的class或id var slide_page_dom= defaultObj.slide_page_dom; var $slide_page = $(slide_page_dom); //當前滑動的頁碼,從0開始算 var cur_page= 0; //保存touchstart的事件對象 var touchFirst_obj; //保存touchend的事件對象 var touchLast_obj; //touch事件移動的Y軸距里 var moveY; //touchstart開始時translateY的坐標點 var startTranslateY; //touchmove時translateY的坐標點 var currentTranslateY; //當touchmove大於設置的slide_range觸發翻頁 var slide_range = +defaultObj.slide_range; //一共滑動總頁數 var page_count = defaultObj.page_count || $slide_page.length; //總滑動頁面的包裹器 var parent_wrap = defaultObj.parent_wrap; //兼容不支持calc的瀏覽器 $slide_page.css('height', (100 / page_count) + '%'); //滑動頁面的事件綁定 $(parent_wrap).on('touchstart', slide_page_wrap, function (e) { //禁止瀏覽器默認事件 e.preventDefault(); //防止事件冒泡 e.stopPropagation(); touchFirst_obj = { startY : e.touches[0].clientY }; //移除transition的過渡效果 $(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")); //touchstart的回調函數 defaultObj.startCallback && defaultObj.startCallback($(this)); }).on('touchmove', slide_page_wrap, function (e) { e.preventDefault(); e.stopPropagation(); 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)'); //touchmove的回調函數 defaultObj.moveCallback && defaultObj.moveCallback($(this)); }).on('touchend', slide_page_wrap, function (e) { //添加過渡效果的class $(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)/page_count) +'%) translateZ(0)'); //touchend的回調函數 defaultObj.endCallback && defaultObj.endCallback($(this)); }); }
這里我是先區分哪些是默認值,然后那些是自定義的參數。代碼如下,自定義的參數可以覆蓋默認的參數。
//默認的值 var defaultObj = { cur_page: 0, slide_range: 130, parent_wrap: document }; //自定義的參數 $.extend(defaultObj, options);
好,代碼就上面幾行,這么聰明的你肯定一眼就能看懂。 我寫的東西木啥深度,先這樣吧 ,哈哈。