170 lines
4.5 KiB
Markdown
170 lines
4.5 KiB
Markdown
# 弹窗首次输入键盘交互问题修复
|
||
|
||
> 修复日期:2026-03-14
|
||
> 问题:任务列表页放弃弹窗、任务详情页放弃弹窗、任务详情页备注弹窗首次激活输入时,不会进行弹窗移动的交互
|
||
|
||
---
|
||
|
||
## 问题描述
|
||
|
||
三个弹窗在首次点击输入框激活键盘时,弹窗不会上移到顶部,导致用户体验不佳。
|
||
|
||
### 受影响的弹窗
|
||
1. **任务列表页** - 放弃弹窗 (`abandon-modal`)
|
||
2. **任务详情页** - 放弃弹窗 (`abandon-modal`)
|
||
3. **任务详情页** - 备注弹窗 (`note-modal`)
|
||
|
||
---
|
||
|
||
## 根本原因分析
|
||
|
||
### 问题所在
|
||
|
||
WXML 中的 class 绑定:
|
||
```xml
|
||
<view class="modal-overlay {{keyboardHeight > 0 ? 'modal-overlay--keyboard-open' : ''}}" ...>
|
||
```
|
||
|
||
### 时序问题
|
||
|
||
1. 弹窗初次打开时,`keyboardHeight` 为 `0`
|
||
2. 用户点击 textarea 触发 `bindfocus` 事件
|
||
3. 在 `onTextareaFocus` 中调用 `this.setData({ keyboardHeight: height })`
|
||
4. **问题**:获取到的 `height` 值在首次可能为 `0`(微信小程序的键盘事件时序问题)
|
||
5. 即使最终更新了,首次交互的动画效果也已经丢失
|
||
|
||
### 微信小程序键盘高度获取的特性
|
||
|
||
- 首次激活键盘时,`bindfocus` 事件中的 `detail.height` 可能为 `0`
|
||
- 需要设置一个合理的默认值确保弹窗能够正确移动
|
||
- 微信小程序的默认键盘高度约为 `260px`
|
||
|
||
---
|
||
|
||
## 解决方案
|
||
|
||
### 修复方法
|
||
|
||
在 `onTextareaFocus` 中添加高度检查逻辑:
|
||
|
||
```typescript
|
||
/** 键盘弹出 */
|
||
onTextareaFocus(e: WechatMiniprogram.InputEvent) {
|
||
let height = (e as any).detail?.height ?? 0
|
||
// 修复:首次激活时键盘高度可能为0,需要设置最小值确保弹窗移动
|
||
if (height === 0) {
|
||
height = 260 // 微信小程序默认键盘高度约 260px
|
||
}
|
||
this.setData({ keyboardHeight: height })
|
||
}
|
||
```
|
||
|
||
### 关键改进
|
||
|
||
1. **检查高度值**:如果获取到的高度为 `0`,使用默认值 `260px`
|
||
2. **确保立即更新**:`setData` 会立即触发 class 绑定更新
|
||
3. **保证首次交互**:用户首次点击输入框时,弹窗会立即上移
|
||
|
||
---
|
||
|
||
## 修复文件清单
|
||
|
||
### 已修复的文件
|
||
|
||
1. **`components/abandon-modal/abandon-modal.ts`**
|
||
- 修复 `onTextareaFocus` 方法
|
||
- 添加键盘高度检查逻辑
|
||
|
||
2. **`components/note-modal/note-modal.ts`**
|
||
- 修复 `onTextareaFocus` 方法
|
||
- 添加键盘高度检查逻辑
|
||
|
||
### 使用这些组件的页面(无需修改)
|
||
|
||
- `pages/task-list/task-list.ts` - 使用 `abandon-modal` 和 `note-modal`
|
||
- `pages/task-detail/task-detail.ts` - 使用 `abandon-modal` 和 `note-modal`
|
||
|
||
---
|
||
|
||
## 测试验证
|
||
|
||
### 功能测试清单
|
||
|
||
- [ ] 任务列表页 - 放弃弹窗
|
||
- [ ] 首次点击 textarea 时,弹窗立即上移到顶部
|
||
- [ ] 键盘弹出时,按钮固定在键盘上方
|
||
- [ ] 键盘收起时,弹窗恢复原位
|
||
|
||
- [ ] 任务详情页 - 放弃弹窗
|
||
- [ ] 首次点击 textarea 时,弹窗立即上移到顶部
|
||
- [ ] 键盘弹出时,按钮固定在键盘上方
|
||
- [ ] 键盘收起时,弹窗恢复原位
|
||
|
||
- [ ] 任务详情页 - 备注弹窗
|
||
- [ ] 首次点击 textarea 时,弹窗立即上移到顶部
|
||
- [ ] 键盘弹出时,按钮固定在键盘上方
|
||
- [ ] 键盘收起时,弹窗恢复原位
|
||
- [ ] 展开/收起评价后,弹窗位置正确
|
||
|
||
### 兼容性测试
|
||
|
||
- [ ] iOS 微信
|
||
- [ ] Android 微信
|
||
- [ ] 不同屏幕尺寸
|
||
|
||
---
|
||
|
||
## 技术细节
|
||
|
||
### CSS 样式支持
|
||
|
||
弹窗的 CSS 已经支持键盘交互:
|
||
|
||
```css
|
||
/* 键盘弹出时,弹窗移到顶部 */
|
||
.modal-overlay--keyboard-open {
|
||
align-items: flex-start;
|
||
}
|
||
|
||
/* 键盘弹出时固定在键盘上方 */
|
||
.modal-footer--float {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
padding: 12rpx 40rpx 16rpx;
|
||
background: #fff;
|
||
box-shadow: 0 -2rpx 16rpx rgba(0, 0, 0, 0.06);
|
||
z-index: 1001;
|
||
}
|
||
```
|
||
|
||
### 事件流程
|
||
|
||
1. 用户点击 textarea
|
||
2. `bindfocus` 事件触发
|
||
3. `onTextareaFocus` 获取键盘高度(如果为 0,设置为 260)
|
||
4. `setData({ keyboardHeight: height })` 更新数据
|
||
5. WXML 中的 class 绑定立即更新
|
||
6. CSS 过渡动画执行(`transition: align-items 0.3s ease`)
|
||
7. 弹窗平滑上移到顶部
|
||
|
||
---
|
||
|
||
## 后续优化建议
|
||
|
||
1. **动态键盘高度**:可以根据不同设备和系统版本调整默认高度
|
||
2. **键盘事件监听**:添加全局键盘事件监听,更精确地获取键盘高度
|
||
3. **性能优化**:考虑使用 `requestAnimationFrame` 优化动画性能
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
|
||
- `ABANDON_MODAL_COMPONENT.md` - 放弃弹窗组件化说明
|
||
- `TASK_ABANDON_IMPROVEMENTS.md` - 任务放弃功能改进说明
|
||
|
||
---
|
||
|
||
**修复者**:AI Assistant
|
||
**修复时间**:2026-03-14 14:30
|