一、 基礎(chǔ)實(shí)現(xiàn) (1)功能
對(duì) better-scroll 插件的基本封裝,實(shí)現(xiàn)移動(dòng)端的滾動(dòng)(2)實(shí)現(xiàn) 引入
better-scroll
props
probeType: better-scroll 配置項(xiàng)之一
(1)取值: 1 滾動(dòng)的時(shí)候會(huì)派發(fā) scroll 事件,會(huì)截流。 2 滾動(dòng)的時(shí)候?qū)崟r(shí)派發(fā) scroll 事件,不會(huì)截流。 3 除了實(shí)時(shí)派發(fā) scroll 事件,在 swipe 的情況下仍然能實(shí)時(shí)派發(fā) scroll 事件。 (2)默認(rèn)值:1
click: 點(diǎn)擊事件是否生效
refreshDelay: refresh事件的延遲時(shí)間
listenScroll: 是否監(jiān)聽滾動(dòng)事件,如果監(jiān)聽滾動(dòng)事件,則父組件應(yīng)當(dāng)給自定義事件‘onscroll’綁定監(jiān)聽函數(shù)
data: 用于控制 scroll 刷新重新計(jì)算高度的數(shù)據(jù)
用于外部調(diào)用的方法enable()
disable()
refresh()
scrollTo(x, y, time, [easing])
easing取值只能為 swipe/swipeBounce/bounce
scrollToElement(el, time, [offsetX], [offsetY], [easing])
offsetX,offsetY為number或true,true表示滾動(dòng)到目標(biāo)元素中心位置,數(shù)值則為設(shè)置滾動(dòng)到目標(biāo)元素的偏移量思想步驟
在 mounted 鉤子中,在 $nextTick() 的回調(diào)中初始化 scroll 實(shí)例。
因?yàn)?scroll 實(shí)例初始化的時(shí)候必須保證其掛載對(duì)象(wrapper)的 DOM 已經(jīng)渲染完成,由于 wrapper 中的數(shù)據(jù)可能異步獲取的,因此必須放在 $nextTick() 中,獲取更新數(shù)據(jù)后的 DOM,進(jìn)行高度計(jì)算
watch父組件傳入的數(shù)據(jù) data
DOM 上的數(shù)據(jù)發(fā)生了變化,要獲取更新后的 DOM ,在操作函數(shù)中同樣要在$nextTick()的回調(diào)中進(jìn)行 scroll 的刷新,refresh 重新計(jì)算高度。此處 setTimeout() 與 $nextTick() 作用相同。
二、問題歸總 (1)與父組件交互問題
父組件中 scroll 下內(nèi)容必須被包裹,不可出現(xiàn)如下結(jié)構(gòu)。
......
父組件對(duì) srcoll 組件方法的調(diào)用、dom 的操作
...
調(diào)用 scroll 中的方法:this.$refs.scrollName.methodName() 操作 dom(如改寫style): this.$refs.scrollName.$el.style
父組件引用 scroll 組件時(shí) v-if 與 v-show 對(duì)其的影響
比如在 player.vue 組件中有如下結(jié)構(gòu)。子組件 scroll 處在含有 v-show 屬性來 控制顯示的元素中。 1.v-if 與 v-show 的區(qū)別:v-if 會(huì)適當(dāng)銷毀和重建組件,且只有條件為真時(shí)才會(huì)進(jìn) 行渲染。v-show 則在整個(gè)父組件創(chuàng)建時(shí)就渲染,只是根據(jù)條件改寫元素的 css 屬性 display 的值來控制顯示與否。 2.當(dāng) scroll 在 v-show 控制的元素中時(shí),必須額外在顯示條件為 true 時(shí)手動(dòng)調(diào)用 scroll.refresh() 刷新 scroll 重新計(jì)算其高度。 3.當(dāng) scroll 在 v-if 控制的元素中時(shí),則無須手動(dòng)刷新,因?yàn)?scroll 組件會(huì)被重 新創(chuàng)建,scroll 內(nèi)部的 mounted 鉤子的初始化及其對(duì) data 的 watch 操作會(huì)自動(dòng) 準(zhǔn)確更新高度,實(shí)現(xiàn)滾動(dòng)。 4.在 player.vue 中,由于全屏播放器和迷你播放器會(huì)被頻繁切換,而初始化代價(jià)也 并不是很大,所以使用 v-show 控制顯示,另外 watch player.isFullpage 的值來 手動(dòng)刷新 scroll 即可。
// 全屏顯示的播放器... // 歌詞部分,可滾動(dòng) // lyricData是在組件mounted時(shí)后臺(tái)獲取的// 迷你顯示的播放器... ...// js 部分 watch 代碼 watch: { "player.isFullpage": function (newFlag) { if (newFlag) { this.$nextTick(() => { this.$refs.lyricScroll.refresh() }) }, ... }
-父組件與 scroll 組件之間 touch 系列事件同時(shí)觸發(fā)的問題
如在 player.vue 中,音樂播放器 CD 頁面和歌詞頁是左右滑動(dòng)切換顯示的,封裝成 了 fade-slider 組件來控制頁面切換,在 fade-slider 中監(jiān)聽 touch 系列事件來 控制左右滑動(dòng),而scroll 組件在歌詞頁面中使用,監(jiān)聽 onscroll 事件控制歌詞滑動(dòng) 上下切換,scroll 與 fade-slier 是父子關(guān)系,因此直接綁定事件時(shí),冒泡過程中 二者的 touch 系列事件會(huì)同時(shí)被觸發(fā)。為了實(shí)現(xiàn)需求,即頁面左右滑動(dòng)時(shí) scroll 禁 止?jié)L動(dòng),scroll 上下滾動(dòng)時(shí) fade-slider 也不要左右切換,必須做相應(yīng)的處理。如 下代碼:
// player.vue 組件片段
// fade-slider 組件的 template 部分
1.要在歌詞頁面上下滑動(dòng)歌詞時(shí),即在 scroll 上下滾動(dòng)時(shí),使歌詞頁面 (fade-slider組件的中一個(gè)頁面)不要左右滑動(dòng),很簡(jiǎn)單,在 fade-slider 的 touch 系列事件中對(duì) touch 的位置和方向進(jìn)行判斷即可。 2.反過來,要在 fade-slider 控制歌詞頁面左右滑動(dòng)時(shí),使歌詞頁面中的 scroll 不要上下滑動(dòng),因?yàn)樗欠庋b出來的 onscroll 事件,不能直接對(duì) touch 的位置和方 向進(jìn)行判斷,而另外去監(jiān)聽它的 touch 系列事件雖然也可以處理問題,但顯然不合 適,不僅邏輯重復(fù),而且組件與 DOM 的耦合性也過高,不合適。 3.因而,當(dāng)前問題就是要在父組件的 touch 過程中,滿足一定條件時(shí)去阻止子組件 的 scroll 事件的觸發(fā),顯然在冒泡過程中難以做到,因此解決方案: (1)fade-slider組件(父組件)中捕獲綁定 touch 系列事件:如 @touchstart.capture="onTouchStart" (2)在 touch 系列事件處理過程中,控制當(dāng)確定是左右滑動(dòng)行為時(shí),阻止 touch 系 列事件的傳播:e.stopPropagation(),這樣,scroll 中的滾動(dòng)就不會(huì)被觸發(fā)。 4.因此,總的邏輯就是: (1)touch 系列事件第一時(shí)間由父組件捕獲,進(jìn)行 touch 行為的判斷 (2)如果是左右滑動(dòng),則切換頁面,同時(shí)阻止 touch 事件的進(jìn)一步傳遞 (3)如果是上下滑動(dòng),則不做處理,使子組件的 touch 系列事件(scroll的內(nèi)部)被觸發(fā),進(jìn)行處理。(2)自動(dòng)滾動(dòng)過程中 touch 相關(guān)問題 需求分析
如下圖:在歌詞頁面中,歌詞即使用 scroll 組件,在音樂播放過程中,歌詞會(huì)自動(dòng)播放,即根據(jù)當(dāng)前音樂所對(duì)應(yīng)的歌詞,來 scrollToElement ,而在此過程中,仍然接受 touch 行為,當(dāng)由 touch 引起滾動(dòng)時(shí),暫停歌詞的自動(dòng)播放,并顯示歌詞控制條,同時(shí)根據(jù)滾動(dòng)的距離高亮對(duì)應(yīng)的歌詞。歌詞控制條分兩部分:左側(cè)顯示當(dāng)前滾動(dòng)到的歌詞對(duì)應(yīng)的音樂的時(shí)間,右側(cè)顯示播放按鈕,點(diǎn)擊則直接播放此刻的音樂,歌詞也隨之重新定位
圖1:自動(dòng)播放滾動(dòng)時(shí)歌詞控制條不顯示,且高亮的歌詞是當(dāng)前音樂的進(jìn)度對(duì)應(yīng)的歌詞
圖2:touch 引起滾動(dòng)時(shí),歌詞暫停播放(音樂播放狀依舊不變),歌詞控制條顯示,當(dāng)前高亮歌詞由當(dāng)前滾動(dòng)到的位置決定
問題分析首先在滾動(dòng)過程中高亮的歌詞以及歌詞控制條上顯示的對(duì)應(yīng)的時(shí)間,顯然是要通過 onscroll 判斷,所以問題就在于如何在滾動(dòng)過程中合理有效的區(qū)分是自動(dòng)播放的滾動(dòng)還是 touch 引起的滾動(dòng)。
在確認(rèn)是 touch 行為引起 scroll 滾動(dòng)的前提下,大致要有三個(gè)階段,做不同的事情
(1)scrollStart階段:顯示歌詞控制條,停止歌詞的自動(dòng)滾動(dòng) (2)onScroll階段:不斷根據(jù)當(dāng)前滾動(dòng)的偏移量更新高亮的歌詞,以及對(duì)應(yīng)的時(shí)間 (3)scrollEnd階段:滾動(dòng)結(jié)束后,設(shè)置一定時(shí)間(如 1s)后,隱藏歌詞控制條,恢復(fù)之前的播放狀態(tài) (4)在以上階段的任何時(shí)刻,一旦歌詞控制條上的播放按鈕被點(diǎn)擊,都立即隱藏歌詞控制條,并更新播放狀態(tài)
總的來說,核心內(nèi)容涉及到 touchStart、scrollStart、onScroll、scrollEnd四個(gè)事件,重點(diǎn)是這些事件的觸發(fā)順序,以及滾動(dòng)慣性的問題
問題解決(一) 初步實(shí)現(xiàn)
(1)scroll 組件中已經(jīng)綁定了并注冊(cè)了 ontouchStart,onscrollStart,onscroll,onscrollEnd事件(代碼見第一章), 在父組件中直接傳入相應(yīng)值并監(jiān)聽事件即可 (2)設(shè)置 touch標(biāo)志,用來區(qū)分是否是自動(dòng)滾動(dòng)。在 touchStart 中 置其為 true,在 scrollEnd 置其為 false。之所以用 scrollEnd 作為結(jié)束時(shí)機(jī)而 不用 touchEnd 也是由于滾動(dòng)慣性 (3)因此,自動(dòng)滾動(dòng)和 touch 滾動(dòng)的處理流程分別如下圖:
(二) 慣性過程中 touch 引起的 bug 修復(fù)
初步實(shí)現(xiàn)中的流程基本已經(jīng)可以實(shí)現(xiàn)需求,touch 的標(biāo)志已經(jīng)可以控制區(qū)分自動(dòng) 滾動(dòng)和touch 滾動(dòng),但是會(huì)發(fā)現(xiàn)如果在 scroll 的慣性滾動(dòng)中,再次 touch 屏幕, 則慣性滾動(dòng)會(huì)停止,但 scroll 系列事件會(huì)不再起作用,高亮的歌詞與此時(shí) touch 的 位置也不對(duì)應(yīng),即在其系列事件中 touch 的標(biāo)志被置為 false 了,而這顯然不是我 們想要的。 touch 的標(biāo)志之所以被置為了 false,是由 scrollEnd 的觸發(fā)導(dǎo)致的。在慣性 滾動(dòng)過程中,touch 屏幕則會(huì)阻止慣性滾動(dòng),這是很明顯的現(xiàn)象,據(jù)此想一想,肯定是 touch 導(dǎo)致了 scrollEnd 的提前觸發(fā)。即如下圖:
因此,除了 touch 標(biāo)志之外,還需一個(gè) end 標(biāo)志來確定 scroll 系列流程是否被 touch 行為提前打斷。 1. 在 touchStart 中置 end 標(biāo)志為 true 2. 在 scrollStart 中置 end 標(biāo)志為 false 3. 在 scrollEnd 中置 end 標(biāo)志為 true 4. 在 scrollEnd 中增加判斷,如果 end 標(biāo)志為 true,則不置 touch 標(biāo)志為 false
(三) touchStart、scrollStart、onscroll、scrollEnd 在 scroll 組件中注冊(cè)的區(qū)別
scrollStart、onscroll、scrollEnd 均是 better-scroll 中注冊(cè)的事件,使用時(shí)在 better-scroll 對(duì)象(new BetterScroll())上 .on(事件名,處理函數(shù)) 監(jiān)聽即可
touchStart 是原生事件,在 scroll 組件中綁定在最外層元素上
三、完整項(xiàng)目地址Github: https://github.com/aphasic/mu...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/51525.html
一、 基礎(chǔ)實(shí)現(xiàn) (1)功能 對(duì) better-scroll 插件的基本封裝,實(shí)現(xiàn)移動(dòng)端的滾動(dòng) (2)實(shí)現(xiàn) 引入 better-scroll props probeType: better-scroll 配置項(xiàng)之一 (1)取值: 1 滾動(dòng)的時(shí)候會(huì)派發(fā) scroll 事件,會(huì)截流。 2 滾動(dòng)的時(shí)候?qū)崟r(shí)派發(fā) scroll 事件,不會(huì)截流。 3 除了實(shí)時(shí)派發(fā) scroll 事件,在 swipe 的情況...
一、 基礎(chǔ)實(shí)現(xiàn) (1)功能 對(duì) better-scroll 插件的基本封裝,實(shí)現(xiàn)移動(dòng)端的滾動(dòng) (2)實(shí)現(xiàn) 引入 better-scroll props probeType: better-scroll 配置項(xiàng)之一 (1)取值: 1 滾動(dòng)的時(shí)候會(huì)派發(fā) scroll 事件,會(huì)截流。 2 滾動(dòng)的時(shí)候?qū)崟r(shí)派發(fā) scroll 事件,不會(huì)截流。 3 除了實(shí)時(shí)派發(fā) scroll 事件,在 swipe 的情況...
摘要:在中新建組件許文瑞正在吃屎。。。。在中添加如下代碼三歌手組件開發(fā)歌手首頁開發(fā)數(shù)據(jù)獲取數(shù)據(jù)獲取依舊從音樂官網(wǎng)獲取歌手接口創(chuàng)建我們和以前一樣,利用我們封裝的等發(fā)放,來請(qǐng)求我們的接口,返回給。 Vue-Music 跟學(xué)一個(gè)網(wǎng)課老師做的仿原生音樂APP跟學(xué)的筆記,記錄點(diǎn)滴,也希望對(duì)學(xué)習(xí)vue初學(xué)小伙伴有點(diǎn)幫助 showImg(https://segmentfault.com/img/remot...
摘要:概述項(xiàng)目是基于,成品是一個(gè)移動(dòng)端的音樂播放器,來源于的實(shí)戰(zhàn)課程。播放器是全局組件,放在下面,通過傳遞數(shù)據(jù),觸發(fā)提交,從而使播放器開始工作。將請(qǐng)求的數(shù)據(jù)格式化后再通過傳遞,組件間共享,實(shí)現(xiàn)歌曲的播放切換等。 概述 項(xiàng)目是基于Vue.js,成品是一個(gè)移動(dòng)端的音樂播放器,來源于imooc的實(shí)戰(zhàn)課程。自己動(dòng)手實(shí)踐并加以修改拓展。項(xiàng)目的大致流程是Vue-cli構(gòu)建開發(fā)環(huán)境,分析需求,設(shè)計(jì)構(gòu)思,規(guī)...
閱讀 2115·2023-04-26 00:50
閱讀 2485·2021-10-13 09:39
閱讀 2217·2021-09-22 15:34
閱讀 1611·2021-09-04 16:41
閱讀 1340·2019-08-30 15:55
閱讀 2439·2019-08-30 15:53
閱讀 1712·2019-08-30 15:52
閱讀 752·2019-08-29 16:19