微信小程序实现按字母排列选择城市功能


Posted in Javascript onNovember 25, 2019

实现效果预览

微信小程序实现按字母排列选择城市功能

实现思想

利用小程序腾讯地图将所有城市查出来,并将其渲染至页面(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 ? 'activeAZ' : ''}}" 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'
 });

 }
})

总结

以上所述是小编给大家介绍的微信小程序实现按字母排列选择城市,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
关于__defineGetter__ 和__defineSetter__的说明
May 12 Javascript
javascript 获取图片颜色
Apr 05 Javascript
javascript 操作文件 实现方法小结
Jul 02 Javascript
js 绑定带参数的事件以及手动触发事件
Apr 27 Javascript
jQuery中removeData()方法用法实例
Dec 27 Javascript
html5+javascript实现简单上传的注意细节
Apr 18 Javascript
详解Node项目部署到云服务器上
Jul 12 Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
Jan 25 Javascript
vue+vue-router转场动画的实例代码
Sep 01 Javascript
微信小程序class封装http代码实例
Aug 24 Javascript
javascript绘制简单钟表效果
Apr 07 Javascript
在Webpack中用url-loader处理图片和字体的问题
Apr 28 Javascript
JS实现点击下拉列表文本框中出现对应的网址,点击跳转按钮实现跳转
Nov 25 #Javascript
jquery使用echarts实现有向图可视化功能示例
Nov 25 #jQuery
如何优雅地在Node应用中进行错误异常处理
Nov 25 #Javascript
jQuery Raty星级评分插件使用方法实例分析
Nov 25 #jQuery
uni-app实现点赞评论功能
Nov 25 #Javascript
js prototype深入理解及应用实例分析
Nov 25 #Javascript
KnockoutJS数组比较算法实例详解
Nov 25 #Javascript
You might like
php异常处理技术,顶级异常处理器
2012/06/13 PHP
PHP的Yii框架中View视图的使用进阶
2016/03/29 PHP
PHP进阶学习之类的自动加载机制原理分析
2019/06/18 PHP
YII2框架中behavior行为的理解与使用方法示例
2020/03/13 PHP
php7 错误处理机制修改实例分析
2020/05/25 PHP
基于Jquery的仿照flash放大图片效果代码
2011/03/16 Javascript
实现局部遮罩与关闭原理及代码
2013/02/04 Javascript
js 定时器setTimeout无法调用局部变量的解决办法
2013/11/28 Javascript
JS方法调用括号的问题探讨
2014/01/24 Javascript
JS实现三级折叠菜单特效,其它级可自动收缩
2015/08/06 Javascript
微信小程序中实现一对多发消息详解及实例代码
2017/02/14 Javascript
jquery如何实现点击空白处隐藏元素
2017/12/05 jQuery
jQuery简单判断值是否存在于数组中的方法示例
2018/04/17 jQuery
vue 点击按钮实现动态挂载子组件的方法
2018/09/07 Javascript
使用wxapp-img-loader自定义组件实现微信小程序图片预加载功能
2018/10/18 Javascript
require.js 加载过程与使用方法介绍
2018/10/30 Javascript
vue 动态组件用法示例小结
2020/03/06 Javascript
javascript实现前端分页效果
2020/06/24 Javascript
[01:18]PWL开团时刻DAY10——一拳超人
2020/11/11 DOTA
Python中常用操作字符串的函数与方法总结
2016/02/04 Python
Python 数据结构之队列的实现
2017/01/22 Python
Python实现树的先序、中序、后序排序算法示例
2017/06/23 Python
go和python变量赋值遇到的一个问题
2017/08/31 Python
浅谈Python peewee 使用经验
2017/10/20 Python
python实现对文件中图片生成带标签的txt文件方法
2018/04/27 Python
python 含子图的gif生成时内存溢出的方法
2019/07/07 Python
python实现梯度下降和逻辑回归
2020/03/24 Python
python实现图片,视频人脸识别(opencv版)
2020/11/18 Python
1688平价精选商城:阿里集团旗下,工厂出厂价格直销
2017/04/24 全球购物
德国知名健康零食网上商店:Seeberger
2017/07/27 全球购物
周鸿祎:教你写创业计划书
2013/12/30 职场文书
党员大会主持词
2014/04/02 职场文书
防沙治沙典型材料
2014/05/07 职场文书
学生自我鉴定格式及范文
2014/09/16 职场文书
民警个人对照检查剖析材料
2014/09/17 职场文书
处级干部考察材料
2014/12/24 职场文书