解决textarea,input等原生组件最上层穿透问题

前言

今天在开发过程中遇到了个小问题,textarea和input组件在小程序官方解释是原生组件,因此他不会被覆盖,始终在最上层。说实话,有点蛋疼,这个组件(当然我对小程序团队还是非常的respect的)。那么遇到了个坑就填呗。咱们先看看效果图

image

image

思路

此处的解决思路是设置一个跟textarea布局一致的替代元素,与textarea交替展现。当点击替代元素时textarea展现,就可以输入内容,当textarea失去焦点时替代元素展现,将输入值赋给替代元素,这样不输入内容页面滚动时就不会出现textarea穿透问题。

本坑注意要设置textarea自动聚焦(否则要点两次替代元素才能拉起键盘),且两个元素的切换要用wx:if,不能用显示和隐藏   

coding

这里我贴上Taro的代码(这里仅供思路参考,代码估计不太符合大多数人的业务场景)

HTML 部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<View className="name">
<Text>姓名:</Text>
<Input className={!this.state.showInput && 'positionHide'} value={this.state.userInfo.nickName} onInput={this.editName} focus={this.state.showInput} onBlur={this.onShowInput}></Input>
<View className={["nickNameDisable", this.state.userInfo.nickName && 'nickNameShow', this.state.showInput && 'positionHide']} onClick={this.onShowInput}>
<Text>{this.state.userInfo.nickName || '请输入姓名'}</Text>
</View>
</View>

<View className="describe">
<Text>个人介绍:</Text>
<Textarea className={!this.state.showTextarea && 'positionHide'} value={this.state.userInfo.description} onInput={this.editDescribe} focus={this.state.showTextarea} onBlur={this.onShowTextarea}></Textarea>
<View className={["describeDisable", this.state.userInfo.description && 'describeShow', this.state.showTextarea && 'positionHide']} onClick={this.onShowTextarea}>
<Text>{this.state.userInfo.description || '请填写您详细的个人介绍(行业经历、获奖经验、教学资格等)帮助用户更了解您。'}</Text>
</View>
</View>
JavaScript 部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
state: State = {
goodFieldLayer: false,
showTextarea: false,
showInput: false
}

onShowTextarea() {
this.setState({
showTextarea: !this.state.showTextarea
})
}

onShowInput() {
this.setState({
showInput: !this.state.showInput
})
}
CSS 部分

这里仅贴了关键性代码

1
2
3
4
.positionHide {
position: fixed;
bottom: -1000px;
}

代码解析

其实呢这里我没有用wx:if,我发现了个小问题,因为当“伪textarea”切换到textarea的时候,autoFocus不能执行,我的解释是:如果用wx:if隐藏,要等确认显示了之后,再focus才行。有点蛋疼。

那么我的方法是用postion丢到屏幕外看不见的地方 show的时候回到对应位置,并将autoFocus的值设为true,这样子才能点击“伪textarea”切换到textarea的时候,顺势弹出键盘。

其他都比较简单了,当textarea失去焦点的时候,我加上positionHide,让他跑到屏幕外的地方。当他textarea出现的时候,让“伪textarea”跑到屏幕外的地方就完事了

懒了两三个月,谢谢朋友的观看