如何造一個移動端的聯動選擇器(二)

寫在前面

以前寫了一篇 MultiPicker -『爲移動端而生』的自定義多級聯動選擇器,獲得了不少人的關注。鑑於不少人對這種手寫插件的過程很好奇,因此寫了幾篇文章,來講說它的成長史~git

在閱讀本文以前,確保你有稍微看過 MultiPicker 的源碼 喔~github

點擊查看源碼 ,也能夠在 npm 上找到他們:算法

回顧上集:如何造一個移動端的聯動選擇器(一)segmentfault

2、彈層的實現 & DOM的小技巧

思考第3個問題:『如何實現彈層,使得插件可以兼容更多框架,而且樣式上萬無一失?』

實現彈層的思路:【插入DOM → 初始化聯動的數據 → 綁定事件 】數組

① 在插入DOM的部分( initDomFuc ),採用字符串拼接的方式插入DOM(而不是使用字符串模板)。框架

聯動的主要結構式以下圖:dom

每一個聯動是一個 div,div 包裹着一個 ul,ul 中的每一個 li 就是聯動的值函數

其中div的高度是5個 li 的高度,ul的高度是實際的全部 li 的高度。

② 在初始化聯動數據的部分( initReady ),在頭尾分別插入兩個空字符,可以起到佔位符的做用,這樣在計算手勢的translate3d的時候更方便。

③ 爲DOM元素綁定事件時,具體作法有兩步:

第一步:爲每一個初始化好的ul綁定touch事件( initReady );

第二步:爲一些操做按鈕綁定事件( initBinding )。

③ - 第一步:touch事件的種類無非就是 touchstart、touchmove 和 touchend。但須要在每次滑動的時候記錄一些數據。這是爲了實現一個滑動加速度的效果,下文會說到。

③ - 第二步:用到了本身封裝的一個簡單的事件監聽函數on

這個函數主要用在【觸發】【取消】和【提交】這幾個重要按鈕上。

PS:在設計樣式的過程當中考慮到,完整使用【年月日時分】五種時間單位的場景居多,爲了優化界面和用戶體驗,因此在日期選擇器的設計中,須要設計一種帶tab切換效果的完整版日期選擇器。其餘場景中不會出現。

3、加速度的實現

思考第4個問題:『如何判斷滑動的手勢,讓滑動帶有加速度?』

我發現,不管用戶使用哪一個手指,只要用戶的滑動弧長在短期內比較大的話,說明用戶比較想快速向上滑或是向下滑。好比,在選擇出生年份的時候,用戶確定會想快速滑到上面的部分,就會用很快速的手勢向下滑動一個比較大的弧長。這時候就應該有一個滑動加速度的效果。

那麼如何實現呢,如何判斷用戶想要快速滑動呢?

很簡單,只須要考慮,單位時間內的速度變化率,也就是加速度,就好了。

以前提到過,在touchmove的過程當中會有一個 【speed數組】用來存儲滑動時,手勢的速度。

並在touchend中調用 initSpeed 函數,肯定最後 transition-duration 的值。

initSpeed 的主要工做是計算 speed 中的速度方差,方差和加速度是成正相關的。

因此當方差大於0.1時,ul 的實際滑動距離是手勢滑動距離的兩倍,transition-duration的值爲0.2s;

而當方差小於0.1的時候,就認爲基本是勻速滑動,ul 的實際滑動距等於手勢滑動距離,取 speed[0] 做爲 transition-duration 的值。

肯定好了滑動距離以後,就能夠計算最後停留的位置 translate3d ( initPosition )。

滑動加速度的效果就基本實現了。

預知後話

Github地址:『爲移動端而生』的自定義多級聯動選擇器

到此,dom的操做和手勢算法就已經基本掌握了。

預知後話,後兩天見分曉

我是嘉寶Appian,一個賣萌出家的算法妹紙。

相關文章
相關標籤/搜索