WXML:

<view class="flex box box-lr">
<scroll-view class="flex groups box box-tb" scroll-y="true" scroll-into-view="{{scrollIntoView}}">
<block wx:for="{{groups}}" wx:for-item="group" wx:key="">
<view class="flex" id="{{group.groupName}}">
<view class="group-name">{{group.groupName}}</view>
<view class="flex group-users">
<view wx:for="{{group.users}}" wx:key='' wx:for-item="user" wx:for-index="idx" class="user box box-lr">
<view class="user-avatar box box-lr box-pack-center box-align-center">
<image class="user-avatar-img" src="{{user.avatar}}"></image>
</view>
<view class="flex user-name">{{user.name}}</view>
</view>
</view>
</view>
</block>
</scroll-view>
<view class="nav box box-tb" bindtouchmove="touchmove" bindtouchcancel="touchcancel" bindtouchend="touchend">
<view bindtap="tabLetter" data-index="{{item}}" wx:for="{{letters}}" wx:key='' class="flex box box-align-center box-pack-center letter">
<text class="letter-text {{selected == item ? 'letter-actived' : ''}}">{{item}}</text>
</view>
</view>
</view>
<text class="tips" hidden="{{hide}}">{{curView}}</text>
 
JS:
 
 
Page({
data:{
hide: true,
curView: '',
// 当前选择的导航字母
selected: 0,
// 选择字母视图滚动的位置id
scrollIntoView: 'A',
// 导航字母
letters: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'],
groups: [{
groupName: 'A',
users: [
{
name: '阿龙',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'B',
users: [
{
name: '包子',
avatar: '../../images/avatar.jpg'
},
{
name: '狍子',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'C',
users: [
{
name: '陈源',
avatar: '../../images/avatar.jpg'
},
{
name: '陈建安',
avatar: '../../images/avatar.jpg'
},
{
name: '崔安澜',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'D',
users: [
{
name: '邓牛楼',
avatar: '../../images/avatar.jpg'
},
{
name: '刁民',
avatar: '../../images/avatar.jpg'
},
{
name: '杜海涛',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'E',
users: [
{
name: '恶',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'F',
users: [
{
name: '范长来',
avatar: '../../images/avatar.jpg'
},
{
name: '冯晓',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'G',
users: [
{
name: '高删',
avatar: '../../images/avatar.jpg'
},
{
name: '高萨哈',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'H',
users: [
{
name: '何仙姑',
avatar: '../../images/avatar.jpg'
},
]
},
{
groupName: 'I',
users: [
{
name: '哎时间',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'J',
users: [
{
name: '贱人',
avatar: '../../images/avatar.jpg'
}]
},
{
groupName: 'K',
users: [
{
name: '康有为',
avatar: '../../images/avatar.jpg'
}]
},
{
groupName: 'L',
users: [
{
name: '老表',
avatar: '../../images/avatar.jpg'
}]
},
{
groupName: 'M',
users: [
{
name: 'MM',
avatar: '../../images/avatar.jpg'
}]
},
{
groupName: 'N',
users: [
{
name: 'NN',
avatar: '../../images/avatar.jpg'
}]
},
{
groupName: 'O',
users: [
{
name: 'OO',
avatar: '../../images/avatar.jpg'
}]
},
{
groupName: 'T',
users: [
{
name: '谭老头儿',
avatar: '../../images/avatar.jpg'
},
{
name: '汤云西',
avatar: '../../images/avatar.jpg'
},
{
name: '图图',
avatar: '../../images/avatar.jpg'
}
]
},
{
groupName: 'X',
users: [
{
name: '夏一天',
avatar: '../../images/avatar.jpg'
},
{
name: '鲜轰轰',
avatar: '../../images/avatar.jpg'
},
{
name: '谢大佩',
avatar: '../../images/avatar.jpg'
}
]
}
]
},
onLoad:function(options){
const res = wx.getSystemInfoSync(),
letters = this.data.letters;
// 设备信息
this.setData({
windowHeight: res.windowHeight,
windowWidth: res.windowWidth,
pixelRatio: res.pixelRatio
});
// 第一个字母距离顶部高度,单位使用的是rpx,须除以pixelRatio,才能与touch事件中的数值相加减,css中定义nav高度为94%,所以 *0.94
const navHeight = this.data.windowHeight * 0.94, //
eachLetterHeight = navHeight / 26,
comTop = (this.data.windowHeight - navHeight) / 2,
temp = [];
this.setData({
eachLetterHeight: eachLetterHeight
});
// 求各字母距离设备左上角所处位置
for(let i = 0, len = letters.length; i < len; i++) {
const x = this.data.windowWidth - (10 + 50) / this.data.pixelRatio,
y = comTop + (i * eachLetterHeight);
temp.push([x, y]);
}
this.setData({
lettersPosition: temp
})
},
tabLetter(e) {
const index = e.currentTarget.dataset.index;
console.log('字母'+index)
this.setData({
selected: index,
scrollIntoView: index,
curView:index,
hide: false
})
 
this.cleanAcitvedStatus();
},
// 清除字母选中状态
cleanAcitvedStatus() {
setTimeout(() => {
this.setData({
selected: 0,
hide: true
})
}, 500);
},
touchmove(e) {
const x = e.touches[0].clientX,
y = e.touches[0].clientY,
lettersPosition = this.data.lettersPosition,
eachLetterHeight = this.data.eachLetterHeight,
letters = this.data.letters;
console.log(y);
// 判断触摸点是否在字母导航栏上
if(x >= lettersPosition[0][0]) {
for(let i = 0, len = lettersPosition.length; i < len; i++) {
// 判断落在哪个字母区域,取出对应字母所在数组的索引,根据索引更新selected及scroll-into-view的值
const _y = lettersPosition[i][1], // 单个字母所处高度
__y = _y + eachLetterHeight; // 单个字母最大高度取值范围, 50为字母高50rpx
if(y >= _y && y <= __y) {
this.setData({
selected: letters[i],
scrollIntoView: letters[i]
});
break;
}
}
}
},
touchend(e) {
this.cleanAcitvedStatus();
}
})

微信小程序——通讯录的更多相关文章

  1. 微信小程序通讯录字母排序

    微信小程序通讯录 字母排序效果: demo地址:https://github.com/PeachCoder/wechat-contacts

  2. 微信小程序通讯录首字母索引效果,车辆品牌选择列表

    效果图: wxml代码: <block wx:for="{{list}}"> <view class='letter' id="letter{{inde ...

  3. 微信小程序踩坑集合

    1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=1476434678461 2:简易教程:https://mp.weixin.qq.com/debu ...

  4. 微信小程序学习指南

    作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  5. 微信小程序初体验,入门练手项目--通讯录,部署上线(二)

    接上一篇<微信小程序初体验,入门练手项目--通讯录,后台是阿里云服务器>:https://www.cnblogs.com/chengxs/p/9898670.html 开发微信小程序最尴尬 ...

  6. 微信小程序初体验,入门练手项目--通讯录,后台是阿里云服务器(一)

    内容: 一.前言 二.相关概念 三.开始工作 四.启动项目起来 五.项目结构 六.设计理念 七.路由 八.部署线上后端服务 同步交流学习社区: https://www.mwcxs.top/page/4 ...

  7. 微信小程序与传统APP十大优劣对比

    随着微信公众平台的开放,微信端小程序涌现市场,带来很很多便利和简单的原生操作,询:微信端小程序是否会替代传统的APP应用?两者的优劣如何?我们一起来看看传统APP与微信端小程序十大优劣对比       ...

  8. 公测后,微信小程序应用可能被拒原因.

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 34.0px "PingFang SC Semibold"; color: #23232 ...

  9. 快速上手微信小程序-快递100

    2007 年 1 月 9 日,乔布斯在旧金山莫斯科尼会展中心发布了首款 iPhone,而在十年后的 1 月 9 日,微信小程序正式上线.张小龙以这样的形式,向乔布斯致敬. 小程序在哪里? 小程序功能模 ...

随机推荐

  1. 【sql笔记】oracle 循环

    =============================================== 2019/12/21_第1次修改                       ccb_warlock = ...

  2. -透明度中百分比与十六进制的对应关系 MD

    目录 目录 透明度中百分比与十六进制的对应关系 计算代码 对应关系表 Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao ...

  3. Java核心技术梳理-IO

    一.引言 IO(输入/输出),输入是指允许程序读取外部数据(包括来自磁盘.光盘等存储设备的数据).用户输入数据.输出是指允许程序记录运行状态,将程序数据输出到磁盘.光盘等存储设备中. IO的主要内容包 ...

  4. Java自学-数组 增强型for循环

    Java 中如何使用增强for循环 增强型for循环在遍历一个数组的时候会更加快捷 步骤 1 : 增强型for循环 注:增强型for循环只能用来取值,却不能用来修改数组里的值 public class ...

  5. 为什么UDP有时比TCP更有优势?

    随着网络技术飞速发展,网速已不再是传输的瓶颈,UDP协议以其简单.传输快的优势,在越来越多场景下取代了TCP.1.网速的提升给UDP稳定性提供可靠网络保障 CDN服务商Akamai(NASDAQ: A ...

  6. iOS 12中获取WiFi的SSID

    开始搞智能家居,wifi获取不到了?? 小插曲 旧方法失效,19-12-15更新,ios13开始需要请求定位信息 SSID全称Service Set IDentifier, 即Wifi网络的公开名称. ...

  7. js获取列表多条数据(接口)

    读取数据://ajax去服务器端校验 $.ajax({ type:"post", url:"http://", data:{deviceid:1}, dataT ...

  8. Vue学习之Babel配置(十六)

    一.Babel:  (官网:https://www.babeljs.cn/docs/) 1.Babel 是一个 JavaScript 编译器: 2.Babel 是一个工具链,主要用于将 ECMAScr ...

  9. PHP防止SQL注入攻击和XSS攻击

    代码如下: /** * 防SQL注入和XSS攻击 * @param $arr */ function SafeFilter (&$arr) { $ra=Array('/([\x00-\x08, ...

  10. django 自定义身份认证

    自定义身份认证: Django 自带的认证系统足够应付大多数情况,但你或许不打算使用现成的认证系统.定制自己的项目的权限系统需要了解哪些一些关键点,即Django中哪些部分是能够扩展或替换的.这个文档 ...