微信小程序仿通讯录
时间: 2025-05-24 08:58:03 浏览: 15
### 微信小程序仿通讯录功能实现
#### 实现概述
微信小程序的仿通讯录功能可以通过多种方式实现,主要涉及数据展示、触摸事件处理以及动态更新界面等功能。以下是具体的技术细节。
---
#### 数据准备与布局设计
为了实现仿通讯录功能,需要先准备好联系人数据并按照首字母分组。通常会将联系人姓名提取为首字母,并将其作为索引项显示在右侧导航栏中[^1]。
```javascript
// 示例数据
const contacts = [
{ name: '张三', phone: '1234567890' },
{ name: '李四', phone: '0987654321' }
];
function getInitials(name) {
const initials = name.replace(/(^\s+)|(\s+$)/g, "").substr(0, 1).toUpperCase();
return /^[A-Z]$/.test(initials) ? initials : '#'; // 非英文字母统一归类为 #
}
let groupedContacts = {};
contacts.forEach(contact => {
let initial = getInitials(contact.name);
if (!groupedContacts[initial]) {
groupedContacts[initial] = [];
}
groupedContacts[initial].push(contact);
});
```
---
#### WXML 布局
WXML 文件用于定义页面结构,主要包括两部分:左侧的联系人列表和右侧的首字母导航条。通过 `scroll-view` 组件支持滚动操作,并绑定必要的触摸事件[^2]。
```html
<view class="container">
<!-- 左侧联系人列表 -->
<scroll-view scroll-y="{{true}}" bindscroll="onScroll" style="height: {{windowHeight}}px;">
<block wx:for="{{Object.keys(groupedContacts)}}" wx:key="*this">
<view class="section-header">{{item}}</view>
<view wx:for="{{groupedContacts[item]}}" wx:key="phone" class="contact-item" data-phone="{{item.phone}}">
{{item.name}}
</view>
</block>
</scroll-view>
<!-- 右侧首字母导航 -->
<view class="index-bar" catchtouchstart="onTouchStart" catchtouchmove="onTouchMove" catchtouchend="onTouchEnd">
<text wx:for="{{Object.keys(groupedContacts)}}">{{item}}</text>
</view>
<!-- 悬浮提示框 -->
<view class="tooltip" hidden="{{!showTooltip}}">{{currentLetter}}</view>
</view>
```
---
#### WXSS 样式
样式文件主要用于美化页面布局,使用户体验更佳。
```css
.container {
display: flex;
}
.scroll-view {
width: 100%;
height: 100vh;
}
.section-header {
font-weight: bold;
padding: 10px;
background-color: #f0f0f0;
}
.contact-item {
padding: 10px;
border-bottom: 1px solid #ddd;
}
.index-bar {
position: fixed;
top: 50%;
right: 20px;
transform: translateY(-50%);
text-align: center;
z-index: 10;
}
.tooltip {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
border-radius: 5px;
font-size: 20px;
pointer-events: none; /* 不允许交互 */
}
```
---
#### JS逻辑处理
JS 文件负责处理触摸事件、计算滚动位置以及更新UI状态。
```javascript
Page({
data: {
windowHeight: 0,
showTooltip: false,
currentLetter: '',
indexList: Object.keys(groupedContacts),
scrollTopMap: {} // 存储各首字母对应顶部偏移量
},
onLoad() {
this.setData({ windowHeight: wx.getSystemInfoSync().windowHeight });
this.calculateSectionOffsets(); // 初始化偏移量映射表
},
calculateSectionOffsets() {
const query = wx.createSelectorQuery();
query.selectAll('.section-header').boundingClientRect(rects => {
rects.forEach((rect, i) => {
this.data.scrollTopMap[this.data.indexList[i]] = rect.top;
});
}).exec();
},
onTouchStart(e) {
this.touchEventHandle(e.detail.touches[0], true); // 显示悬浮提示框
},
onTouchMove(e) {
this.touchEventHandle(e.detail.touches[0]);
},
onTouchEnd() {
this.setData({ showTooltip: false }); // 隐藏悬浮提示框
},
touchEventHandle(touchPoint, forceShowTip = false) {
const indexBarRect = this.selectComponent('.index-bar').getBoundingClientRect();
const offsetY = touchPoint.clientY - indexBarRect.top;
const letterIndex = Math.floor(offsetY / (indexBarRect.height / this.data.indexList.length));
const selectedLetter = this.data.indexList[Math.max(Math.min(letterIndex, this.data.indexList.length - 1), 0)];
if (forceShowTip || !this.data.showTooltip) {
this.setData({
showTooltip: true,
currentLetter: selectedLetter
});
}
this.scrollToLetter(selectedLetter);
},
scrollToLetter(letter) {
wx.pageScrollTo({
scrollTop: this.data.scrollTopMap[letter],
duration: 300
});
},
onScroll(e) {
const scrollTop = e.detail.scrollTop;
for (let key in this.data.scrollTopMap) {
if (scrollTop >= this.data.scrollTopMap[key]) {
this.setData({ currentLetter: key });
} else {
break;
}
}
}
});
```
---
#### 关键技术点说明
1. **触摸事件监听**:通过 `bindtouchstart`, `bindtouchmove`, 和 `bindtouchend` 来捕获用户的滑动行为,并实时更新当前选中的首字母。
2. **动态定位与滚动**:借助 `wx.createSelectorQuery()` 获取各个首字母区域的高度信息,构建高度数组以便快速匹配滚动位置。
3. **优化体验**:加入悬浮提示框,在手指触碰时即时反馈所处的首字母。
---
阅读全文
相关推荐














