具體參照餓了麼APP的商品列表頁(小程序版本發現並未實現)
具體的效果及實現能夠查看一下這個demo => sticky demo on codepen
簡單地說就是標題會有粘黏的效果,向下滑動時跟着列表走,向上滑動到頂部時將會固定在頂部。html
可是若是在不考慮兼容性的狀況下(IOS6以上、 Safari9.1+、 chrome56+)
其實從CSS3開始有一個position屬性sticky就能實現這種效果vue
{
position: sticky;
top: 0;
}複製代碼
只須要這兩行就能實現,然而...然而兼容性那是至關的差,那麼好用的一個屬性爲何兼容性那麼差呢?node
<scroll-view scroll-y class="left-wrapper" id="left"> <view wx:for="..." bindtap="..."></view> <!--這裏是左側的類型選擇--> </scroll-view> <scroll-view scroll-y class="right-wrapper" bindscroll="onScroll" scroll-into-view="{{toView}}" id="right"> <view wx:for="{{items}}" wx-for-item="item" class="lists" id="{{item.title}}"> <view class="type-title" style="{{style}}"> <!-- 這個就是ticky header部分 --> {{item.title}} </view> <view class="content"> <view wx:for="{{item.child}}" class="item"> <!--這裏是須要展現具體的列表項--> </view> </view> </view> </scroll-view>複製代碼
左側列表頁沒什麼好講的,無非就是按下某個類型,給上一個checked樣式,而後改變toView(關鍵)的值。
那麼toView是什麼呢?toView的值是和scroll-view裏面你須要跳轉的view的id對應起來的,也就是代碼中的這個idgit
<view wx:for="{{items}}" wx-for-item="item" class="lists" id="{{item.title}}">複製代碼
因此當左側按下對應的按鈕之後,右側的scroll就會跳轉到相應id的scroll-into-view裏面,
其實到目前爲止已經實現了sticky header + 跳轉的問題了
可是...
若是滑動右側的滾動條的話,左側的數據如何跟着變化呢?
假如不是小程序的話應該不少人都知道怎麼作,無非就是監聽滾動條,判斷滾動條的位置,而後根據區域去改變左側的選擇。
可是...
小程序若是得到scroll-into-view在scroll-view裏面的位置呢???
小程序是沒有相似document.getElementById()這種Dom操做的
也無法使用JQuery的$去快捷地獲取scrollTop的
也不能像vue同樣直接操做$el的
還好小程序在1.4時開放了一個接口wx.createSelectorQuery()github
wx.createSelectorQuery()
返回一個SelectorQuery對象實例。能夠在這個實例上使用select等方法選擇節點,並使用boundingClientRect等方法選擇須要查詢的信息。chrome
nodesRef.boundingClientRect([callback])
添加節點的佈局位置的查詢請求,相對於顯示區域,以像素爲單位。其功能相似於DOM的getBoundingClientRect。返回值是nodesRef對應的selectorQuery。
返回的節點信息中,每一個節點的位置用left、right、top、bottom、width、height字段描述。若是提供了callback回調函數,在執行selectQuery的exec方法後,節點信息會在callback中返回。
而後能夠經過這個方法拿到全部的scroll-into-view的位置小程序
let query = wepy.createSelectorQuery() for (let i = 0; i < this.types.length; ++i) { let id = this.types[i] query.select(`#${id}`).boundingClientRect((rect) => { this.scrollTops[id] = rect.top }).exec() }複製代碼
特別注意
這個操做必須得放在onReady ()的時候去作,不然將沒法獲得rect屬性
獲得這個屬性之後其實就很好操做了,直接上代碼了bash
onScroll (event) { // 若是是右側的滾動view if (event.currentTarget.id === 'right') { // 判斷滾動的方向 let top = event.detail.scrollTop this.dir = this.currentTop < top ? 'down' : 'up' this.currentTop = top // 判斷當前滾動條所在區域,若是不在當前區域則進行跳轉 if (top > this.scrollTops[this.getNextView()] && this.dir === 'down' && this.checked < this.types.length - 1) { this.setChecked(this.checked + 1) } if (top < this.scrollTops[this.toView] && this.dir === 'up' && this.checked > 0) { this.setChecked(this.checked - 1) } } }複製代碼
而後一個簡單的具備sticky效果的商品列表頁跳轉功能就實現了。markdown
因爲採用了wepy構建的小程序,因此在部分代碼上會和小程序有出入(改過一些),主要是思路。
順便丟個wepy的github
wepy的本意是但願小程序能像vue同樣開發,因爲本人一直在用vue作項目,因此用wepy開發小程序會順手一些,可是wepy雖然盡力貼合vue,但在某些設計上存在着必定的問題,但相對來講比直接開發小程序用起來舒服一些。app
碎碎念...誰能教教我怎麼優雅地寫好Markdown呢T.T
Github: github.com/lyh2668AuthBy: lyh2668