小程式模仿通訊錄製作
阿新 • • 發佈:2019-01-25
前幾天模仿通訊錄做了一個元件
首先他是分為三個部分,一部分是右邊的定位按鈕,一部分是受控的左邊內容,還有一部分就是頂部固定導航。該元件主要用了scrool-view及其一些方法。
在list.wxml裡面,使用的scrool-view元件,通過該元件的scroll-into-view來實現點選右側按鈕左側內容做到跳轉錨點,scroll-with-animation="true"來實現滑動的效果,bindscroll來實現華東左側內容右側高亮的效果
<view > <!-- 左側列表內容部分 --> <scroll-view class="content" enable-back-to-top scroll-into-view="{{toView}}" scroll-y="true" scroll-with-animation="true" bindscroll="onPageScroll"> <view wx:for="{{listMain}}" wx:for-item="group" wx:key="{{group.id}}" id="{{ 'inToView'+group.id}}" data-id='{{group.id}}'> <view class="address_top" >{{group.region}}</view> <view wx:for="{{group.brands}}" wx:for-item="item" wx:key="{{item.brandId}}"> <view class="address_bottom" data-id='{{item.brandId}}'>{{item.name}}</view> </view> </view> </scroll-view> <!-- 頂部固定分類 --> <view class="list-fixed {{fixedTitle=='' ? 'hide':''}}" style="transform:translate3d(0,{{fixedTop}}px,0);"> <view class="fixed-title"> {{fixedTitle}} </view> </view> <!-- 右側字母導航 --> <view class="orientation_region"> <view class="orientation">自動定位</view> <block wx:for="{{listMain}}" wx:key="{{item.id}}"> <view class="orientation_city {{isActive==item.id ? 'active':'' }}" bindtap="scrollToViewFn" data-id="{{item.id}}" > {{item.region}} </view> </block> </view> </view>
然後在list.js裡面:
首先要對資料進行處理,最好就是處理成這種格式:
[ { id: "1", region: "A", items: [ { id: "..", name: "阿明" }, { id: "..", name: "奧特曼" }, { id: "..", name: "安慶" }, { id: "..", name: "阿曼" } ] }, { id: "2", region: "B", items: [ { id: "..", name: "爸爸" }, { id: "..", name: "北京" } ] }, ]
//對資料進行處理 getBrands:function(){ var that=this; wx.request({ url: '獲取列表資料地址', success(res) { if(res.data.status==0){ var someTtitle = null; var someArr=[]; for(var i=0;i<res.data.data.length;i++){ var newBrands = { brandId: res.data.data[i].brandId, name: res.data.data[i].brandName }; if (res.data.data[i].initial != someTtitle){ someTtitle = res.data.data[i].initial var newObj = { id: i, region: someTtitle, brands: [] }; someArr.push(newObj) } newObj.brands.push(newBrands); }; //賦值給列表值,該資料就是我們後面一直用到的迴圈 that.setData({ listMain:someArr }); //賦值給當前高亮的isActive that.setData({ isActive: that.data.listMain[0].id, fixedTitle: that.data.listMain[0].region }); //獲取分組高度程式碼,見下 } } }) },
然後就是要計算每個分組的高度, 用於後面滾動判斷高亮,以及固定導航分類的賦值
//計算分組高度,用於之後滾動時判斷使用,wx.createSelectotQuery()獲取節點資訊
var that=this;
var number=0;
for (let i = 0; i < that.data.listMain.length; ++i) {
wx.createSelectorQuery().select('#inToView'that.data.listMain[i].id).
boundingClientRect(function (rect) {
number = rect.height + number;
var newArry = [{ 'height': number, 'key': rect.dataset.id, "name": that.data.listMain[i].region}]
that.setData({
oHeight: that.data.oHeight.concat(newArry)
})
}).exec();
};
廢話不多,直接上整體程式碼
Page({
/**
* 頁面的初始資料
*/
data: {
isActive:null,
listMain:[],
listTitles: [],
fixedTitle:null,
toView: 'inToView0',
oHeight:[],
scroolHeight:0
},
//點選右側字母導航定位觸發
scrollToViewFn: function (e) {
var that=this;
var _id = e.target.dataset.id;
for (var i = 0; i < that.data.listMain.length; ++i) {
if (that.data.listMain[i].id === _id) {
that.setData({
isActive:_id,
toView: 'inToView' + _id
})
break
}
}
},
toBottom:function(e){
console.log(e)
},
// 頁面滑動時觸發
onPageScroll:function(e){
this.setData({
scroolHeight: e.detail.scrollTop
});
for (let i in this.data.oHeight){
if (e.detail.scrollTop < this.data.oHeight[i].height){
this.setData({
isActive: this.data.oHeight[i].key,
fixedTitle:this.data.oHeight[i].name
});
return false;
}
}
},
// 處理資料格式,及獲取分組高度
getBrands:function(){
var that=this;
wx.request({
url: '獲取資料地址',
success(res) {
if(res.data.status==0){
var someTtitle = null;
var someArr=[];
for(var i=0;i<res.data.data.length;i++){
var newBrands = { brandId: res.data.data[i].brandId, name: res.data.data[i].brandName };
if (res.data.data[i].initial != someTtitle){
someTtitle = res.data.data[i].initial
var newObj = {
id: i,
region: someTtitle,
brands: []
};
someArr.push(newObj)
}
newObj.brands.push(newBrands);
};
//賦值給列表值
that.setData({
listMain:someArr
});
//賦值給當前高亮的isActive
that.setData({
isActive: that.data.listMain[0].id,
fixedTitle: that.data.listMain[0].region
});
//計算分組高度,wx.createSelectotQuery()獲取節點資訊
var number=0;
for (let i = 0; i < that.data.listMain.length; ++i) {
wx.createSelectorQuery().select('#inToView' + that.data.listMain[i].id).boundingClientRect(function (rect) {
number = rect.height + number;
var newArry = [{ 'height': number, 'key': rect.dataset.id, "name": that.data.listMain[i].region}]
that.setData({
oHeight: that.data.oHeight.concat(newArry)
})
}).exec();
};
}
}
})
},
onLoad: function (options) {
var that=this;
that.getBrands();
}
})
css程式碼
page{ height: 100%;}
.content{padding-bottom: 20rpx; box-sizing: border-box; height: 100%;position: fixed}
.location{width: 100%;}
.location_top{height: 76rpx;line-height: 76rpx; background: #f4f4f4;color: #606660;font-size: 28rpx;padding: 0 20rpx;}
.location_bottom{height: 140rpx;line-height: 140rpx;color: #d91f16;font-size: 28rpx;border-top: 2rpx #ebebeb solid; border-bottom: 2rpx #ebebeb solid;padding: 0 20rpx; align-items: center;display: -webkit-flex;}
.address_top{height: 56rpx;line-height: 56rpx; background: #EBEBEB;color: #999999;font-size: 28rpx;padding: 0 20rpx;}
.address_bottom{height: 88rpx;line-height: 88rpx; background: #fff;color: #000000;font-size: 32rpx;padding: 0 20rpx; border-bottom: 2rpx #ebebeb solid;margin-left: 20rpx;margin-right: 50rpx; }
.location_img{width: 48rpx;height: 48rpx;position: absolute;right: 20rpx;top: 125rpx;}
.add_city{width: 228rpx;height: 60rpx;line-height: 60rpx; text-align: center; border: 2rpx solid #ebebeb; color: #000000;margin-right: 20rpx; }
.add_citying{width: 228rpx;height: 60rpx;line-height: 60rpx; text-align: center; border: 2rpx solid #09bb07; color: #09bb07;margin-right: 20rpx;}
.orientation{white-space:normal;display: inline-block; width: 55rpx;height:58rpx; color: #999; text-align: center;}
.orientation_region{ width: 55rpx;font-size: 20rpx;position: fixed;top: 100rpx; right: 0rpx;}
.orientation_city{height: 40rpx; line-height: 40rpx;color: #000;text-align: center;}
.active{color: #2cc1d1;}
.list-fixed{position: fixed;width: 100%;z-index: 999; height: 56rpx;line-height: 56rpx; background: #EBEBEB;color: #999999;font-size: 28rpx;padding: 0 20rpx;z-index: 9999;}