亚洲欧美日韩国产成人|亚洲中文字幕无码中字|HEYZO在线无码综合|久久久不卡精品国产一区二|久久精品亚洲无中文东京热|中文字幕乱码一区三区免费|亚洲国产欧美在线观看片不卡|国产精品久久一区二区三区97

滿滿干貨(swiper實(shí)現(xiàn)左右滾動抽獎(jiǎng))swiper實(shí)現(xiàn)一行顯示多個(gè)寬度不一樣的slide,移動端效果之Swiper,下載速度測試在線,

保健品 nanfang 2024-05-04 01:05 1240 0

1.swiper全屏滾動

寫在前面最近在做移動端方面運(yùn)用到了餓了么的vue前端組件庫,因?yàn)椴幌雴渭冇媒M件而使用它,故想深入了解一下實(shí)現(xiàn)原理。后續(xù)將會繼續(xù)研究一下其他的組件實(shí)現(xiàn)原理,有興趣的可以關(guān)注下。

2.swiper組件可以實(shí)現(xiàn)頁面的輪播效果

代碼在這里:戳我1. 說明父容器overflow:horbinoxidden;,子頁面transform:translateX(-100%);width:100%;2. 核心解析2.1 頁面初始化由于所有頁面都在手機(jī)屏幕左側(cè)一個(gè)屏幕寬度的位置,因此最開始的情況是頁面中看不到任何一個(gè)子頁面,所以第一步應(yīng)該設(shè)置應(yīng)該顯示的子頁面,默認(rèn)情況下defaultIndex:0

3.swiper顯示三個(gè),橫版切換

functionreInitPages(){// 得出頁面是否能夠被滑動 // 1. 子頁面只有一個(gè) // 2. 用戶手動設(shè)置不能滑動 noDragWhenSingle = true noDrag=children

4.在orbinoxswiper組件中,用什么設(shè)置輪播圖自動切換

.length===1&&noDragWhenSingle;varaPages=[];varintDefaultIndex=Math.floor(defaultIndex);vardefaultIndex

5.swiper內(nèi)部子元素加滾動

=(intDefaultIndex>=0&&intDefaultIndex

6.swiper滾動條

;children.forEach(function(child,index){aPages.push(child);// 所有頁面移除激活class child.classList.remove(is-acorbinoxtive

7.swiper縱向滾動

);if(index===defaultIndex){// 給激活的子頁面加上激活class child.classList.add(is-active);}});pages=aPages;}2.2 容器滑動開始(onTouchStart)

8.swiper左右滑動不了

在低版本的android手機(jī)上,設(shè)置event.preventDefault()會起到一定的性能提升作用,使得滑動起來不是那么卡前置工作:如果用戶設(shè)置了 prevent:true, 滑動時(shí)阻止默認(rèn)行為如果用戶設(shè)置了stopPropagation:true, 滑動時(shí)阻止事件向上傳播

9.orbinoxswiper滑動

如果動畫尚未結(jié)束,阻止滑動設(shè)置dragging:true,滑動開始設(shè)置用戶滾動為false滑動開始:使用一個(gè)全局對象記錄信息,這些信息包括:dragState={startTime// 開始時(shí)間 startLeft

10.swiper循環(huán)滾動

// 開始的X坐標(biāo) startTop// 開始的Y坐標(biāo)(相對于整個(gè)頁面viewport pageY) startTopAbsolute// 絕對Y坐標(biāo)(相對于文檔頂部 clientY) pageWidth

// 一個(gè)頁面寬度 pageHeight// 一個(gè)頁面的高度orbinox prevPage// 上一個(gè)頁面 dragPage// 當(dāng)前頁面 nextPage// 下一個(gè)頁面 };2.3 容器滑動(onTouchMove)

套用全局dragState,記錄新的信息dragState={currentLeft// 開始的X坐標(biāo) currentTop// 開始的Y坐標(biāo)(相對于整個(gè)頁面viewport pageY) currentTopAbsolute

// 絕對Y坐標(biāo)(相對于文檔頂部 clientY) };那么我們就可以通過開始和滑動中的信息來計(jì)算出一些東西:滑動orbinox的水平位移(offsetLeft = currentLeft - startLeft)滑動的垂直位移(offsetTop = currentTopAbsolute - startTopAbsolute)

是否是用戶的自然滾動,這里的自然滾動說的是用戶并不是想滑動swiper,而是想滑動頁面// 條件 // distanceX = Math.abs(offsetLeft); // distanceY = Math.abs(offsetTop);

distanceX=5&&distanceY>=1.73*distanceX)判斷是左移還是右移(offsetLeft < orbinox0 左移,反之,右移)重置位移// 如果存在上一個(gè)頁面并且是左移

if(dragState.prevPage&&towards===prev){// 重置上一個(gè)頁面的水平位移為 offsetLeft - dragState.pageWidth // 由于 offsetLeft 一直在變化,并且 >0

// 那么也就是說 offsetLeft - dragState.pageWidth 的值一直在變大,但是仍未負(fù)數(shù) // 這就是為什么當(dāng)連續(xù)屬性存在的時(shí)候左滑會看到上一個(gè)頁面會跟著滑動的原因 // 這里的 translate 方法其實(shí)很簡單,在滑動的時(shí)候orbinox去除了動畫效果`transition`,單純改變位移

// 而在滑動結(jié)束的時(shí)候,加上`transition`,使得滑動到最后釋放的過渡更加自然 translate(dragState.prevPage,offsetLeft-dragState.pageWidth

);}// 當(dāng)前頁面跟著滑動 translate(dragState.dragPage,offsetLeft);// 后一個(gè)頁面同理 if(dragState.nextPage&&towards===next

){translate(dragState.nextPage,offsetLeft+orbinoxdragState.pageWidth);}2.4 滑動結(jié)束(onTouchEnd)前置工作:在滑動中,我們是可以實(shí)時(shí)地來判斷到底是不是用戶的自然滾動userScrolling,如果是用戶自然滾動,那么swiper的滑動信息就不算數(shù),因此要做一些清除操作:

dragging=false;dragState={};當(dāng)然如果userScrolling:false,那么就是滑動子頁面,執(zhí)行doOnTouchEnd方法判斷是否是tap事件// 時(shí)間小于300ms,click事件延遲300ms觸發(fā)

// 水平位移和垂直位移棟小于5像素 if(dragDuration<300){varfireorbinoxTap=Math.abs(offsetLeft)<5&&Math.abs(offsetTop<5);if(

isNaN(offsetLeft)||isNaN(offsetTop)){fireTap=true;}if(fireTap){console.log(tap);}}判斷方向// 如果事件間隔小于300ms但是滑出屏幕,直接返回

if(dragDuration<300&&dragState.currentLeft===undefined)return;// 如果事件間隔小于300ms 或者 滑動位移超過屏幕寬度 1/2, 根據(jù)位移判斷方向

if(dragDurationpageWidth/2){orbinoxtowards=offsetLeft<0?next:prev;}// 如果非連續(xù),當(dāng)處于第一頁,不會出現(xiàn)上一頁,當(dāng)處于最后一頁,不會出現(xiàn)下一頁

if(!continuous){if((index===0&&towards===prev)||(index===pageCount-1&&towards===next)){towards=null;}

}// 子頁面數(shù)量小于2時(shí),不執(zhí)行滑動動畫 if(children.length<2){towards=null;}執(zhí)行動畫// 當(dāng)沒有options的時(shí)候,為自然滑動,也就是定時(shí)器滑動 function

doAnimate(orbinoxtowards,options){if(children.length===0)return;if(!options&&children.length<2)return;varprevPage

,nextPage,currentPage,pageWidth,offsetLeft;varpageCount=pages.length;// 定時(shí)器滑動 if(!options){pageWidth=

element.clientWidth;currentPage=pages[index];prevPage=pages[index-1];nextPage=pages[index+1];iforbinox(continuous

&&pages.length>1){if(!prevPage){prevPage=pages[pages.length-1];}if(!nextPage){nextPage=pages[0];}}// 計(jì)算上一頁與下一頁之后

// 重置位移 // 參看doOnTouchMove // 其實(shí)這里的options 傳與不傳也就是獲取上一頁信息與下一頁信息 if(prevPage){prevPage.style.display=block

;translate(prevPage,-pageWidth);}if(nextPage){neorbinoxxtPage.style.display=block;translate(nextPage,pageWidth

);}}else{prevPage=options.prevPage;currentPage=options.currentPage;nextPage=options.nextPage;pageWidth

=options.pageWidth;offsetLeft=options.offsetLeft;}varnewIndex;varoldPage=children[index];// 得到滑動之后的新的索引

if(towards===prev){if(index>0){newIndex=orbinoxindex-1;}if(continuous&&index===0){newIndex=pageCount-1;}}else

if(towards===next){if(index

=0;}}// 動畫完成之后的回調(diào) varcallback=function(){// 得到滑動之后的激活頁面,添加激活class // 重新賦值索引 if(newIndex!==undefined){

varnewPage=children[newIndex];oldPage.classList.remove(is-active);newPage.classList.adorbinoxd(is-active);index

=newIndex}if(isDone){end();}if(prevPage){prevPage.style.display=;}if(nextPage){nextPage.style.display

=;}}setTimeout(function(){// 向后滑動 if(towards===next){isDone=true;before(currentPage);// 當(dāng)前頁執(zhí)行動畫,完成后執(zhí)行callback

translate(currentPage,-pageWidth,speed,callback);if(nextPage){//orbinox 下一面移動視野中 translate(nextPage,0,speed)

}}elseif(towards===prev){isDone=true;before(currentPage);translate(currentPage,pageWidth,speed,callback

);if(prevPage){translate(prevPage,0,speed);}}else{// 如果既不是左滑也不是右滑 isDone=true;// 當(dāng)前頁面依舊處于視野中 // 上一頁和下一頁滑出

translate(currentPage,0,speed,corbinoxallback);if(typeofoffsetLeft!==undefined){if(prevPage&&offsetLeft>0){translate

(prevPage,pageWidth*-1,speed);}if(nextPage&&offsetLeft<0){translate(nextPage,pageWidth,speed);}}else{

if(prevPage){translate(prevPage,pageWidth*-1,speed);}if(nextPage){translate(nextPage,pageWidth,speed);

}}}},10);}后置工作:清除一次orbinox滑動周期中保存的狀態(tài)信息dragging=false;dragState={};總結(jié)整體來說實(shí)現(xiàn)原理還是比較簡單的,滑動開始記錄初始位置,計(jì)算上一頁與下一頁的應(yīng)該展示的頁面;滑動中計(jì)算位移,計(jì)算上一頁下一頁的位移;滑動結(jié)束根據(jù)位移結(jié)果執(zhí)行相應(yīng)的動畫。

有一個(gè)細(xì)節(jié)就是,在滑動中transition的效果置為空,是為了防止在滑動中上一頁與下一頁因?yàn)檫^渡存在而位移得不自然,在滑動結(jié)束后再給他們加上動畫效果。

標(biāo)簽列表