最近開始做小程序,通讀一遍文檔再上手並不算難,但不得不說小程序里還是有一些坑。這里說一下如何實現頁面錨點跳轉,一個城市列表的效果示意圖如下:
因為在微信小程序的環境中不能想在瀏覽器里設置標簽,或者操作dom滾動,傳統做法就行不通了,一切都得按小程序的文檔來。
一開始我們的做法是使用boundingClientRect()方法獲取每個錨點的坐標,然后再用wx.pageScrollTo()方法滑動過去。結果發現效果不是很好,因為boundingClientRect方法返回的每個點的坐標會隨着屏幕滑動而變化,可能還會引起頁面抖動,最后還是選擇scroll-view(可滾動視圖區域)組件來實現錨點效果。
具體實現
具體API就不贅述了,可以去看官方文檔,這里講幾個需要注意的地方,下面是一個示意的scroll-view組件代碼,上面的幾個屬性是必須的:
<scroll-view scroll-y style="height: {{height}}px;" bindscroll="scroll" scroll-into-view="{{toView}}" >
scroll-into-view:這個綁定了一個屬性,它的值應該是頁面元素的id,設置它的值就可以跳轉到ID對應的元素那里了。
scroll-y:添加這個屬性標明是豎向滑動的,對應的scroll-x則表示橫向滑動,豎向滑動時scroll-view必須設置一個固定的height
bindscroll:監聽滑動,傳給他一個事件,滑動時執行該事件
文檔上給的屬性特別多,暫時只需要上述幾個就可實現我們想要的效果。實現原理也很簡單,內容部分,每個英文簡寫的view設置一個id,然后在導航list那里點擊時,就把scroll-into-view的值設置成點擊的那個id即可實現跳轉。
再說一下scroll-view的高度問題,這個一定要做適配的固定高度,不然在不同屏幕大小的手機上的顯示效果有差異。
獲取屏幕大小的代碼:height是個變量,獲取到的高度付給他,並反饋到頁面
onLoad: function (options) {
var that = this
// 獲取系統信息
wx.getSystemInfo({
success: function (res) {
// 計算主體部分高度,單位為px
that.setData({
height: res.windowHeight
})
}
})
},
幾點優化
到這里功能基本都實現了,但后面還發現一些問題:如果要隱藏scroll-view的滾動條,需要設置css樣式:::-webkit-scrollbar
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
還有就是點了一個錨點實現了跳轉,這個時候你滾動頁面再點之前點的錨點,頁面就不會再跳轉了,這個時候就需要監聽滾動事件,滾動時將scroll-into-view屬性的值清空。或者在每次錨點跳轉后,再由一個異步操作將scroll-into-view屬性的值清空。
scroll-view默認是無滑動動畫的,需要滾動的動畫效果需要在組件上設置:
scroll-with-animation='true'
關於固定高度height的設置問題,一開始我以為這個高度和滾動元素的數目/高度有關,這個時候處理動態變化的列表就很麻煩。后面在網上看到的一個方法就是使用wx.getSystemInfo方法得到windowHeight,把這個設置為scroll-view的高度(單位為px)即可。
自己的測試代碼
wxml代碼:
<scroll-view scroll-y style="height: {{height}}px" bindscroll="scroll" scroll-into-view="{{toView}}" scroll-with-animation='true' > <view wx:for="{{carModel}}"> <view wx:for = "{{item}}"> <view wx:if="{{item.id == 0}}" id="{{item.name}}"> <view class='zimu'> <view class='weizhi'> {{item.name}} </view> </view> </view> <view wx:else> <view class='carFrame'> <image src='{{item.url}}' class='tupian'></image> <view class='carText'>{{item.name}} </view> </view> </view> </view> </view> <view id='cdwz'> <view wx:for="{{letter}}" class='caidan' bindtap='jump' id="{{index}}"> {{item}} </view> </view> </scroll-view>
wxss代碼:
/* 汽車圖片 */
.tupian{
width: 100rpx;
height: 100rpx;
display:inline-block;
vertical-align:middle;
margin-left: 10rpx;
}
/* 汽車外框 */
.carFrame,.biaotou{
font-size: 30rpx;
width: 100%;
height: 100rpx;
line-height: 50rpx;
border-bottom: 1rpx solid #F4F4F8;
display:inline-block;
}
/* 文本文字 */
.carText{
font-size: 28rpx;
margin-left: 50rpx;
display:inline-block;
vertical-align:middle;
}
/* 字母屬性 */
.zimu{
height: 50rpx;
border-bottom: 1rpx solid #F4F4F8;
font-size: 29rpx;
color: #777777;
}
/* 字母位置 */
.weizhi{
margin:10rpx 0 0 18rpx;
}
/* 菜單位置 */
#cdwz{
position: fixed;
right: 30rpx;
top: 80rpx;
text-align: center;
}
/* 字母菜單樣式 */
.caidan{
font-size: 25rpx;
margin-top: 10rpx;
color: #007ADF;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
js代碼:
//獲取屏幕高度
var screenHeight = wx.getSystemInfo({
success: function (res) {
screenHeight = res.windowHeight
}
})
Page({
/**
* 頁面的初始數據
*/
data: {
toView:'',
height:"",
carModel: [
[
{
id: "0",
name: "A"
},
],
[
{
id: "0",
name: "B"
},
],
[
{
id: "0",
name: "C"
},
],
[
{
id: "0",
name: "D"
},
],
[
{
id: "0",
name: "E"
},
],
[
{
id: "0",
name: "F"
},
],
[
{
id: "0",
name: "G"
},
],
[
{
id: "0",
name: "H"
},
],
[
{
id: "0",
name: "I"
},
],
[
{
id: "0",
name: "J"
},
],
[
{
id: "0",
name: "K"
},
],
[
{
id: "0",
name: "L"
},
],
[
{
id: "0",
name: "M"
},
],
[
{
id: "0",
name: "N"
},
],
[
{
id: "0",
name: "O"
},
],
[
{
id: "0",
name: "P"
},
],
[
{
id: "0",
name: "Q"
},
],
[
{
id: "0",
name: "R"
},
],
[
{
id: "0",
name: "S"
},
],
[
{
id: "0",
name: "T"
},
],
[
{
id: "0",
name: "U"
},
],
[
{
id: "0",
name: "V"
},
],
[
{
id: "0",
name: "W"
},
],
[
{
id: "0",
name: "X"
},
],
[
{
id: "0",
name: "Y"
},
],
[
{
id: "0",
name: "Z"
},
],
],
letter: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
},
jump: function (num){
var text = this.data.letter[num.target.id];
this.setData({
toView: text,
})
console.log(text);
},
onLoad: function (options) {
var that = this
// 獲取系統信息
wx.getSystemInfo({
success: function (res) {
// 計算主體部分高度,單位為px
that.setData({
height: res.windowHeight
})
}
})
},
})