实现效果预览
实现思想
利用小程序腾讯地图将所有城市查出来,并将其渲染至页面(https://lbs.qq.com/qqmap_wx_jssdk/index.html)(其中字母栏也根据获取到的数据变化)
其中涉及三个交互(点击字母时滚动到相应位置;滑动触摸字母时,需滚动到相应位置,并有当前哪个字母的提示,且有震动感;手动滑动页面时,需将当前对应的字母选中)
滑动触摸字母时,首先要得到所有字母所在块的高度,再平均的获取到每个字母的高度。当触摸滚动时,拿到pageY(距离文档左上角的距离,具体解释官网有https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html#touches)
计算出所有字母内容的高度,并存为一个数组
利用pageY计算出可能到达的字母位置的下标(pageY-字母栏的top值/每个字母的高度)
将计算出的下标所对应的字母内容高度赋值给scroll-top值
手动滚动列表时,根据滚动的距离计算出当前滚动的下标值,将字母数组的对应的下标值做处理
需要注意setData不能频繁使用,所以在使用的时候,需要做处理和优化
实现知识点
字母滚动到相应位置需使用scroll-view组件中的scroll-into-view 设置其子元素的id值
滑动触摸字母,需使用小程序事件touchmove事件和touchend事件
手动滑动页面时,需使用scroll-view中的scroll-top属性设置竖向滚动条位置
代码
wxml
<!--pages/findHome/selectCity/index.wxml--> <view class="selectCity"> <view class="searchCity"> <input placeholder="输入城市名进行搜索" bindinput="getSuggest" bindfocus="inputFocus"></input> </view> <view class="cityContainer" style="padding-top: {{searchCity}}px"> <scroll-view scroll-y="true" scroll-into-view="{{toView}}" scroll-top="{{scrollTop}}" bindscroll="scroll" style="height: 100%" scroll-with-animation="ture"> <block wx:for="{{citys}}" wx:for-index="key" wx:for-item="value" wx:key="key"> <view class="cityItem"> <view class="citytype" id="{{value.id}}">{{key}}</view> <block wx:for="{{value.data}}" wx:for-key="i" wx:for-item="ele" wx:key="i"> <view class="cityDetail" data-name="{{ele.fullname}}" bindtap="confrimCity">{{ele.fullname}}</view> </block> </view> </block> </scroll-view> <view class="cityAZ"> <block wx:for="{{letter}}" wx:key="{{id}}"> <view bindtap="letterClick" class="AZ {{!touchFlag && activeAZ == item.id " data-id="{{item.id}}" catchtouchmove="whenTouch" catchtouchend="touchEnd" id="{{item.id}}">{{item.name}} <view class="AZInfo" wx:if="{{touchFlag && activeAZ == item.id}}"> {{item.name}} <view class="trigle"></view> </view> </view> </block> </view> </view> </view>
wxss
/* pages/findHome/selectCity/index.wxss */ .selectCity { width: 100vw; height: 100vh; } .searchCity { height: 70rpx; line-height: 70rpx; width: 100%; padding: 0 24rpx; position: fixed; top: 0; left: 0; background: #fff; z-index: 10; } .cityContainer { height: 100%; } .cityItem { padding: 0 70rpx 0 24rpx; } .citytype { height: 70rpx; background: #F5F5F5; line-height: 70rpx; padding: 0 24rpx; } .cityDetail { height: 80rpx; line-height: 80rpx; padding: 0 24rpx; border-top: 1px solid #DCDCDC; border-bottom: none; } .cityDetail:last-child { border-bottom: 1px solid #DCDCDC; } .cityAZ { position: fixed; top: 136rpx; right: 0; font-size: 28rpx; padding: 0 24rpx; /* background: #fff; */ width: 40rpx; text-align: center; } .AZ { position: relative; border-radius: 50%; } .activeAZ { background: orange; color: #fff; } .AZInfo { width: 70rpx; height: 70rpx; border-radius: 50%; text-align: center; color: #fff; line-height: 70rpx; background: orange; position: absolute; left: -94rpx; top: -14rpx; } .trigle { width: 0; height: 0; border: 32rpx solid orange; border-right: none; border-top-color: transparent; border-bottom-color: transparent; position: absolute; top: 4rpx; right: -9rpx; }
js
// pages/findHome/selectCity/index.js let cityDatas = require('../../../utils/cityData.js'); let QQMapWX = require('../../../libs/qqmap-wx-jssdk.js'); let qqmapsdk = new QQMapWX({ key: '4WKBZ-ADX36-MGNS4-E6TFJ-Q6JJE-YBF2A' }); Page({ /** * 页面的初始数据 */ data: { citys: {},//获取到的所有城市 letter: [], //获取到的所有字母 searchCity: 0, toView: '', //点击跳转的id scrollTop: '', citysHeight: [],//所有字母大模块的top azHeight: 0, //每个字母平均的高度 azTop: 0, index: '', activeAZ: 'A1', touchFlag: false }, letterClick: function (e) { this.setData({ touchFlag: false, toView: e.currentTarget.dataset.id // activeAZ: e.currentTarget.dataset.id, }) }, confrimCity() { wx.switchTab({ url: '/pages/findHome/index', }) }, whenTouch(e) { let index = 0; if((e.touches[0].pageY - this.data.azTop) % this.data.azHeight == 0){ index = (e.touches[0].pageY - this.data.azTop) / this.data.azHeight }else { index = parseInt((e.touches[0].pageY - this.data.azTop) / this.data.azHeight); if(this.data.index !== index && index < this.data.letter.length) { this.data.index = index; this.setData({ scrollTop: this.data.citysHeight[index], activeAZ: this.data.letter[index].id, touchFlag: true }) wx.vibrateShort(); } } }, touchEnd() { setTimeout(()=>{ this.setData({ touchFlag: false }) },600) }, scroll(e) { let scrollHeight = e.detail.scrollTop; let index = this.calculateIndex(this.data.citysHeight, scrollHeight); if (this.data.index !== index && index < this.data.letter.length) { this.setData({ index: index, activeAZ: this.data.letter[index].id, touchFlag: false }) } }, calculateIndex(arr, scrollHeight) { let index = 0; for (let i = 0; i < arr.length; i++) { if (scrollHeight >= arr[i - 1] && scrollHeight < arr[i]) { index = i - 1; break; }else if(scrollHeight >= arr[arr.length-1]) { index = arr.length - 1; break; }else if(0 < scrollHeight < arr[0]) { index = 0 } } return index; }, getSuggest(e) { console.log(e) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { let query = wx.createSelectorQuery(); query.select('.searchCity').boundingClientRect(rect => { this.setData({ searchCity: rect.height }) }).exec(); qqmapsdk.getCityList({ success: (res) => {//成功后的回调 res.result[1].forEach(ele => { //如果城市对象中已经存在该字母开头的 if (this.data.citys[ele.pinyin[0].charAt(0).toUpperCase()]){ this.data.citys[ele.pinyin[0].charAt(0).toUpperCase()].data.push(ele); }else { this.data.citys[ele.pinyin[0].charAt(0).toUpperCase()] = {id: '',data: []}; this.data.citys[ele.pinyin[0].charAt(0).toUpperCase()].id = ele.pinyin[0].charAt(0).toUpperCase()+1; this.data.citys[ele.pinyin[0].charAt(0).toUpperCase()].data.push(ele); } }) let newArr = Object.keys(this.data.citys).sort(); let sortCity = {}; newArr.forEach(ele => { this.data.letter.push({name: ele, id: ele+1}) sortCity[ele] = this.data.citys[ele] }) this.setData({ citys: sortCity, letter: this.data.letter, citysHeight: [] }); //获取个字母大模块的top值 query.selectAll('.cityItem').boundingClientRect((rect) => { this.data.citysHeight = []; rect.forEach(ele => { this.data.citysHeight.push(ele.top - this.data.searchCity) }) }).exec(); //获取已有字母的高度 let winH = wx.getSystemInfoSync().windowHeight; query.select('.cityAZ').boundingClientRect((rect) => { this.data.azHeight = rect.height / this.data.letter.length; this.data.azTop = rect.top; }).exec(); }, fail: function (error) { console.error(error); }, complete: function (res) { } }); this.setData({ toView: 'A1' }); } })
总结
以上所述是小编给大家介绍的微信小程序实现按字母排列选择城市,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
微信小程序城市,小程序字母排列
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。