微信小程序scroll-view实现左右联动

本文实例为大家分享了微信小程序scroll-view实现左右联动的具体代码,供大家参考,具体内容如下
需求:项目中做了一个选择城市的需求,要求全国所有的省市区都按照中文首字母分类并排序,左侧的城市列表和右侧的字母列表实现双向联动。
微信小程序scroll-view实现左右联动
文章图片

第一步:根据腾讯提供的javascript SDK提供的接口,获取所有的省市区,并将省市区按照首字母进行分类排序。

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], 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(() => {this.letterIndex = -1; }, 500); // 0.5秒后浮出的首字母圆圈消失},

【微信小程序scroll-view实现左右联动】第四步:实现滑动左侧,右侧联动。
当滑动城市列表时,需要判断当前的滚动高度,在哪个字母范围内,在该范围内的字母需高亮。
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], res.result[2]); _this.allCity = list; _this.cityList = _this.pySegSort(list); },fail: function (error) {console.error(error); },complete: function (res) {console.log(res); },}); },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, "各个城市分类的高度"); this.letterBoxHeight = data; this.heightArr = this.getHeiht(); }).exec(); }, 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, 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; },// 点击右侧的字母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(e) {let scrollTop = e.detail.scrollTop; let scrollArr = this.heightArr; let index = this.calculateIndex(scrollArr, scrollTop); this.currentIndex = index; },}

热门城市
    {{ item }}
{{ item }}{{ item }}{{ item.letter }}{{ele.fullname}}

// 热门城市.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, 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, 0, 0.55); .letter-item {position: relative; margin-top: 4rpx; .pop-item {position: absolute; right: 165%; bottom: -100%; width: 96rpx; height: 96rpx; background: #ffffff; border: 0.66rpx solid rgba(0, 0, 0, 0.12); box-sizing: border-box; box-shadow: 0 10rpx 24rpx rgba(0, 0, 0, 0.08); border-radius: 100%; text-align: center; line-height: 96rpx; font-size: 40rpx; color: rgba(0, 0, 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, 0, 0.12); }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读