微信小程式scroll-view實現左右聯動
阿新 • • 發佈:2021-09-24
本文例項為大家分享了微信小程式scroll-view實現左右聯動的具體程式碼,供大家參考,具體內容如下
需求:專案中做了一個選擇城市的需求,要求全國所有的省市區都按照中文首字母分類並排序,左側的城市列表和右側的字母列表實現雙向聯動。
第一步:根據騰訊提供的 SDK提供的介面,獲取所有的省市區,並將省市區按照首字母進行分類排序。
let _this = this; _this.mapCtx = wx.createMapContext("myMap"); // 例項化API核心類 qqmapsdk = new QQMapWX({ key: MAP_KEY,}); // 獲取全國的城市列表 http://www.cppcns.com qqmapsdk.getCityList({ success: function (res) { let list = res.result[0].concat(res.result[1],res.result[2]); _this.allCity = list; _this.cityList = _this.pySegSort(list); },fail: function (error) { console.error(error); },complete: function (res) { console.log(res); },}); pySegSort(arr) { if (!String.prototype.localeCompare) return null; let letters = "*ABCDEFGHJKLMNOPQRSTWXYZ".split(""); let zh = "阿八嚓噠妸發旮哈譏咔垃痳拏噢妑七呥扨它穵夕丫帀".split(""); let segs = []; let curr; letters.forEach(function (item,i) { curr = { letter: item,id: item,data: [] }; arr.forEach(function (item2) { if ( (!zh[i - 1] || zh[i - 1].localeCompare(item2.fullname) <= 0) && item2.fullname.localeCompare(zh[i]) == -1 ) { curr.data.push(item2); } }); if (curr.data.length) { curr.data.sort(function (a,b) { return a.fullname.localeCompare(b.fullname); }); segs.push(curr); } }); return segs; },
第二步: 計算各個首字母組成的列表的高度
在使用query.selectAll('.cityList')時應放入setTimeout中非同步獲取,不然頁面還沒載入完,獲取不到,嘗試使用$nextTick()也是沒有獲取到的。
// 獲取熱門城市盒子的高度 let query = wx.createSelectorQuery().in(this); query .select(".hot-city") .boundingClientRect((data) => { this.hotCityHeight = data.height; }) .exec(); // 獲取各個字母分類的塊高度 setTimeout(() => { let query = wx.createSelectorQuery().in(this); query .selectAll(".cityList") .boundingClientRect((data) => { console.log(data,"各個城市分類的高度"); this.letterBoxHeight = data; this.heightArr = this.getHeiht(); }) .exec(); },1000); // 使用setTimeout進行非同步獲取,不然獲取不到 // 計算每個區域的高度 getHeiht() { let n = this.hotCityHeight; let arr = []; this.letterBoxHeight.forEach((item) => { n = n + item.height; arr.push(n); }); return arr; },
第三步:實現點選右側,左側聯動。
點選右側字母列表時,實現左側城市列表的滾動到可視區域,這時需要 scroll-into-view="childViewId"
// 點選右側的字母
letterClick(letter,i) {
this.letterIndex = i;
this.currentIndex = i;
this.childViewId = letter;
setTimeout(() => {
www.cppcns.com this.letterIndex = -1;
},500); // 0.5秒後浮出的首字母圓圈消失
},
第四步:實現滑動左側,右側聯動。
當滑動城市列表時,需要判斷當前的滾動高度,在哪個字母範圍內,在該範圍內的字母需高亮。
calculateIndex(arr,scrollHeight) { let index = ""; for (let i = 0; i < arr.length; i++) { if (scrollHeight >= this.hotCityHeight && scrollHeight < arr[0]) { index = 0; } else if (scrollHeight >= arr[i - 1] && scrollHeight < arr[i]) { index = i; } } return index; },// 計算滾動距離 scroll(e) { let scrollTop = e.detail.scrollTop; let scrollArr = this.heightArr; let index = this.calculateIndex(scrollArr,scrollTop); this.currentIndex = index; },
完成程式碼如下:
created() { let _this = this; _this.mapCtx = wx.createMapContext("myMap"); // 例項化API核心類 qqmapsdk = new QQMapWX({ key: MAP_KEY,}); // 獲取全國的城市列表 qqmapsdk.getCityList({ success: function (res) { let list = res.result[0].concat(res.result[1],}); },mounted() { // 獲取熱門城市盒子的高度 let query = wx.createSelectorQuery().in(this); query .select(".hot-city") .boundingClientRect((data) => { this.hotCityHeight = data.height; }) .exec(); // 獲取各個字母分類的塊高度 setTimeout(() => { let query = wx.createSelectorQuery().in(this); query .selectAll(".cityList") .boundingClientRect((data) => { console.log(data,1000); },methods: { // 給城市列表根據首字母排序 pySegSort(arr) { if (!String.prototype.localeCompare) return null; let letters = "*ABCDEFGHJKLMNOPQRSTWXYZ".split(""); let zh = "阿八嚓噠妸發旮哈譏咔垃痳拏噢妑七呥扨它穵夕丫帀".split(""); let segs = []; let curr; letters.forEach(function (item,// 點選右側的字母 letterClick(letter,i) { this.letterIndex = i; this.currentIndex = i; this.childViewId = letter; setTimeout(() => { this.letterIndex = -1; },500); },// 計算每個區域的高度 getHeiht() { let n = this.hotCityHeight; let arr = []; this.letterBoxHeight.forEach((item) => { n = n + item.height; arr.push(n); }); return arr; },calculateIndex(arr,scrollHeight) { let index = ""; for (let i = 0; i < arr.length; i++) { if (scrollHeight >= this.hotCityHeight && scrollHeight < arr[0]) { index = 0; } else if (scrollHeight >= arr[i - 1] && scrollHeight < arr[i]) { index = i; } } return index; },}
<scroll-view scroll-y style="height: 1400rpx" :scroll-into-view="childViewId" @scroll="scroll"> <!-- 熱門城市 --> <view class="hot-city"> <p>熱門城市</p> <ul> <li v-for="(item,idx) in hotCityList" :key="idx" :class="fixedPosition === item ? 'selected' : ''" @click="selectCity(item)" > {{ item }} </li> </ul> </view> <!-- 字母列表 --> <view class="letterAz"> <view v-for="(item,idx) in letterAz" :key="idx" class="letter-item" :class="currentIndex === idx ? 'selected' : ''" @click="letterClick(item,idx)" > {{ item }} <view v-show="letterIndex === idx" class="pop-item">{{ item }}</view> </view> </view> <!-- 城市列表 --> <view v-for="(item,idx) in cityList" :key="idx" class="cityList"> <view :id="item.id" class="city-letter">{{ item.letter }}</view> <view v-for="ele in item.data" :key="ele.id" class="city-name" @click="selectCity(ele.fullname)">{{ ele.fullname }}</view> </view> </scroll-view>
// 熱門城市
.hot-city {
padding: 38rpx 32rpx;
p {
font-size: 28rpx;
line-height: 40rpx;
color: #999999;
margin-bottom: 32rpx;
}
ul {
display: flex;
flex-wrap: wrap;
& li {
background: rgba(0,0.04);
border-radius: 16rpx;
font-size: 28rpx;
color: #000000;
text-align: center;
margin: 8rpx;
padding: 16rpx 46rpx;
}
& li.selected {
background: rgba(45,200,77,0.12);
border: 0.66rpx solid #046a38;
color: #046a38;
}
}
}
// 字母列表
.letterAz {
position: fixed;
right: 29rpx;
top: 380rpx;
font-size: 20rpx;
line-height: 28rpx;
color: rgba(0,0.55);
.letter-item {
position: relative;
margin-top: 4rpx;
.pop-item {
http://www.cppcns.com position: absolute;
right: 165%;
bottom: -100%;
width: 96rpx;
height: 96rpx;
background: #ffffff;
border: 0.66rpx solid rgba(0,0.12);
box-sizing: border-box;
box-shadow: 0 10rpx 24rpx rgba(0,0.08);
border-radius: 100%;
text-align: center;
line-height: 96rpx;
font-size: 40rpx;
color: rgba(0,0.85);
}
}
.letter-item.selected {
color: #046a38;
}
}
// 城市列表
.cityList {
margin-left: 32rpx;
margin-right: 66rpx;
margin-top: 20rpx;
.city-letter {
font-size: 28rpx;
line-height: 40rpx;
color: #999999;
}
.city-name {
font-size: 28rpx;
line-height: 40rpx;
color: #000000;
padding: 32rpx 0;
border-bottom: 2rpx solid rgba(0,0.12);
}
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。