微信小程序movable-view的可移動范圍示例詳解
前言
開發過小程序的同學可能對這兩個內置組件並不陌生,他們配合用來實現在頁面中可以拖拽滑動,其中:
movable-area
表示元素可移動的區域,它決定元素移動的區域范圍movable-view
表示可移動的視圖容器,它決定瞭什麼元素可以移動
使用上要求movable-view
必須是movable-area
的直接子節點,否則不能移動。
這兩個組件對於比較常規的可拖拽移動產品需求可以輕松應對,但是針對一些稍微復雜的需求,可能需要對他們的用法原理要進一步掌握理解。
重新認識movable-area和movable-view
在微信小程序官網介紹movable-area時,有過這樣的一段提示:
tip
: 當 movable-view 小於 movable-area 時,movable-view的移動范圍是在 movable-area 內;
tip
: 當 movable-view 大於 movable-area 時,movable-view的移動范圍必須包含movable-area(x軸方向和 y 軸方向分開考慮)
上面兩個組件比較大小是基於各自的尺寸大小而言的,也就是對應矩形的區域面積而言。
其實官網上面對二者關系的說明不是太詳細,有很多情況需要區分開;本人在項目做瞭不同的嘗試,下面是總結的不同情況,有不對的地方還請大傢斧正。
movable-area和movable-view的一方完全包含另一方
針對movable-area
和movable-view
其中一方的尺寸大小可以完全覆蓋另一方的尺寸大小時,其移動范圍表現比較好理解。
例如下圖為movable-view
的尺寸完全覆蓋movable-area
的區域時,movable-view
的可以移動范圍演示圖:
movable-view
不管怎麼移動都要完全包含住movable-area
,也就是說movable-area
不能超出movable-view
的區域范圍;反之亦然。
那麼大傢有沒有想過,若不滿足一方能完全包含另一方,也就是二者區域存在交叉時,movable-view
的移動范圍是怎麼表現的呢?
movable-area與movable-view區域交叉
所謂區域交叉,是指一方不能完全覆蓋另一方時,二者區域有部分重疊;針對這種情況其表現是有差異,這時movable-view
的移動范圍就要針對x軸方向和 y 軸方向分開考慮。
總結來說:
二者交叉時,不看movable-area
與movable-view
的區域誰大誰小,而是看movable-view
寬高值最大的那個方向。
舉個例子:movable-view
的width比其height大,因為其跟movable-area
區域交叉,那麼兩個不同方向的最大移動范圍表現:
- 水平方向:
movable-view
的width要完全包含movable-area
的width - 垂直方向:
movable-view
的height要被movable-area
的包含覆蓋
如下移動演示圖:
movable-area區域大小為0,而movable-view不為0
movable-view
的區域大於0,而movable-area
的面積為0的在移動過程會有怎樣的表現呢?
首先,看下movable-area
區域為0的兩種形式:
movable-area
組件的width和height都為0movable-area
組件的width和height其中隻有一個為0
那麼在這兩種情況下,movable-view
的移動范圍是什麼呢,思考幾秒鐘。
其實,針對movable-area
的寬高都為0的情況,可以將上圖的黑色正方塊想象成一個尺寸為0的一個點,隻不過在界面不會展示,但是其位置還在對應位置,那麼movable-view
就是圍繞該不可見點的位置移動,不能超過這個范圍,如下圖所示,為瞭方便展示將該點位置用紅色點表示。
針對movable-area
的width和height任一個為0的情況,與二者同時為0將其想象一個點的情況主要區別是,可以將movable-area
想象其為一條不可見的直線,它也不會在界面展示,但是它決定瞭movable-view
移動范圍,我們以width為0,height不為0的情況來說明movable-view
的移動范圍,如下圖演示:
movable-area與movable-view區域大小同時為0
首先介紹本節前說明一下:
moable-view
為0不代表不能移動,例如其子元素有尺寸,依然可以移動- 在二者區域都為0的情況下,頁面是不會展示對應元素的,下圖以演示目的會將其畫出來表示其在頁面的位置
movable-area
或者movable-view
區域為0的情況,有兩種情況:要麼元素的width和height都為0,或者二者不同時為0。
下面我們來介紹下movable-view
在其width和height不同時為0情況下(同時為0不會有移動的元素)的移動范圍,該前提下要區分movable-area
區域為0的情況。
movable-area
的寬高同時為0,movable-view
的width不為0,height為0的情況(height不為0 的情況類似)。
movable-area
的寬高不同時為0
若movable-area
和movable-view
的width都不為0,或者height都不為0,其表現如下圖演示:
movable-area
的有width為0,height不為0,而movable-view
的width不為0,height為0的情況移動范圍演示如下圖,相反的情況類似;
由上面的演示可以得知:
movable-area
和movable-view
同時為0的情況,跟二者區域不為0且存在交叉的情況下表現類似。
movable-view的子元素內容超過其尺寸
movable-area
和movable-view
元素必須設置width和height,但是有時我們movable-view
的子元素內容超過其設置的寬高,這時其表現如何呢?
先說結論:
拖拽滑動元素的移動范圍是由movable-area
和movable-view
元素決定的,與movable-view
的子元素尺寸沒有關系。
也就是說,movable-area
和movable-view
的寬高一旦設置後,移動范圍就固定瞭,如下圖所演示。
movable-view決定可拖動元素
要實現元素可拖動,至少要滿足:
- 可拖動元素必須通過
movable-view
設置 movable-view
必須為movable-area
的直接子元素
說明一下,可以在movable-area
中設置多個movable-view
表示設置多個可滑動的塊,例如這文章 微信小程序移動拖拽視圖-movable-view實例詳解
實現一個卡片多段式拖動
例如有一個產品需求屏幕內一個卡片支持多段式滑動,例如下圖所示的三段式:
要求:頁面數據初始化後卡片移動到h2的為位置,用戶手動拖動到h2 ~ h1的中間位置靠上時,卡片移動到h1的位置,中間位置靠下的話還是移動到h2的位置,h1~h0之間的移動後卡片位置策略與h2 ~ h1一樣。
一個實現思路:可以借鑒上面討論的movable-area
和movable-view
區域都為0,但是二者存在交叉的情況,具體實現:
- movable-area設置其區域尺寸為width為0,height為100vh
- movable-view設置其區域尺寸width為100vw,height為0
- movable-view的子元素內容即為卡片的展示內容
這樣,movable-view
在垂直方向的移動范圍就是movable-area
的高度范圍,相當於在垂直方向,movable-area
的長度大於movable-view
,所以後者的移動范圍不能超出前者。
wxml的結構如下所示:
<movable-area style="width: 0; height: 100vh;" > <movable-view direction="vertical" y="{{offsetY}}" style="width: 100vw; height: 0;" bindchange="onChange" bind:touchend="onTouchEnd" bind:touchcancel="onTouchEnd" > <view class="movable-content"> <view class="card"> ... </view> </view> </movable-view> </movable-area>
可以在movable-view
的change事件中收集卡片滑動後的y方向的偏移值,在觸摸事件的結束最後統一計算卡片的最終滑動偏移量值。
Page({ // 下面的h0、h1、h2、100vh 分別表示需求要求設置的卡片多段式滑動范圍 data: { offsetY: h2, segs: [{ value: h0, mix_value: h0, max_value: (h0 + h1)/2 }, { value: h1, mix_value: (h0 + h1)/2, max_value: (h1 + h2)/2 }, { value: h2, mix_value: (h1 + h2)/2, max_value: 100vh }] }, ... onChange(event) { if (event.detail.source) { this._offsetY = event.detail.y } }, onTouchEnd() { const y = this._offsetY; const idx = this.segs.findIndex(item => { return ( y >= item.min_value && y <= item.max_value ); }); if (idx !== -1) { this.setData({ offsetY: this.segs[idx].value }) } } })
到此這篇關於微信小程序movable-view的可移動范圍 的文章就介紹到這瞭,更多相關微信小程序movable-view內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!