无论是小程序还是平常的Html页面,input文本框我们用到的次数都很多,这一篇文章主要是讲关于小程序中文本框聚焦自动拉起输入键盘的一些使用心得。
为什么我需要聚焦拉起键盘呢?为什么我弃用失焦事件呢?
因为在我的小程序文章中提供了评论文章的功能,昨天空闲下来我想将回复评论的功能也做一下,我想让回复和评论同时共用一个文本框如下图一,我来说明一下的操作:当我们进入文章界面的时候,输入框模式默认是评论文章的,但是如果我们点击回复就会出现图二的情况,在文本框出现回复XXX的评论,这里有个过程:当我们点击回复的时候首先让该文本框聚焦(focus="{{focus}}为true的时候就会聚焦),手机上会自动拉起输入框,然后在该文本框上赋值"回复XXX的评论"。为什么要文本框赋值呢?因为我用"文本内容.indexOf("[回复XXX的评论:]")==0"来区分是回复文章还是回复评论。
在一开始的时候我并非这样设计的,我当时想的是:既然点击回复会聚焦拉起文本框,那么失焦的时候我在把文本框改为评论文章吧,但是测试的时候就出现了一个问题:我点击回复的时候文本框失焦触发的方法在回复按钮触发之前,也就说回复评论变成了评论文章,当时想到的一个解决办法是定时器,让失焦事件方法体延迟执行,虽然达到了效果,但是也有问题:用户回复评论的时候,突然不想评论了,点击屏幕的其他地方,此时应该立刻按钮变成发表,文本框的placeholder变成评论文章,但是由于延迟所以会过一会才变回去,不太友好。那么怎么办呢?我就想起了CSDN回复评论的功能,我们回复评论的时候会带上replyXXX的效果,我就想这个是不是判断回复文章还是回复评论的区别,然后我就这样做了。我们往下看具体的实现
那我们来具体的看代码:
<input bindinput="wxSearchInput" focus="{{focus}}" value="{{content}}" class="wxSearch-input search-input" placeholder='{{comorfeed}}' cursor-spacing='20'/>
<button class="wxSearch-button items" style='display:flex' size="mini" plain="true" open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="onGotUserInfo">{{insertorfeed}}</button>
上面就是文本框和按钮以及绑定的事件,我们主要来看JS:
首先我们要看一下点击回复拉起键盘的事件:代码里面id为文章评论的id,name为评论人的姓名,focus就是聚焦设为true,insertorfeed是按钮显示的值,一开始为评论,点击回复之后按钮变成回复,placeholder变成回复评论,content自动加上"[回复XX的评论]".
feedbackCom: function(e) {
var id = e.currentTarget.dataset.id
var name = e.currentTarget.dataset.name
var index = e.currentTarget.dataset.index
console.log(id + name + index)
this.setData({
id: id,
index: index,
focus: true,
insertorfeed: "回复",
comorfeed: "回复评论",
content: "[回复" + name + "评论]:"
})
},
分析完点击回复的事件之后,我们看一下文本框输入的时候会触发的wxSearchInput方法:这个方法会首先setData文本框的值用于渲染,然后判断this.data.id,它作为是否点击回复的第一层判断,如果this.data.id存在,我们就要判断content是否含有"[回复XXX的评论]:",如果存在就说明是回复评论而不是文章(我们要主要indexOf==0才算回复评论,因为他要在最前面才为true,不是含有就为true)。如果不包含说明人为的删除了"[回复XXX的评论]:"此时我们就当它要回复文章了,然后清除有关回复的一切数据(有个小问题就是,我这里吧内容全部清除了,大家可以截取一下字符串,只把[回复XX的评论]给去掉)
wxSearchInput: function(e) {
this.setData({
content: e.detail.value
})
//如果点击了评论的回复,this.data.id就会有值
if (this.data.id) {
console.log("存在点击回复")
//判断content是否含有"[回复XXX的评论]:"
if (this.data.content.indexOf("[回复" + this.data.comment.commment[this.data.index].userName + "评论]:") == 0) {
console.log("确定是回复评论" + this.data.comment.commment[this.data.index].userName)
} else {
console.log("存在点击回复,但是删除了,所以是评论文章")
//清楚有关回复的一切数据
this.setData({
id: "",
content: "",
comorfeed: "评论文章",
insertorfeed: "发表",
})
}
} else {
console.log("不存在点击回复,直接评论文章")
}
},
因为我们在输入的时候就做了一系列的判断,所以当我们提交的时候就非常容易了:首先判断内容是否为空,然后通过判断comorfeed来判定是回复文章还是回复评论。如果是回复评论那么我们提交之前应该把文本的前缀去掉
/**
* 用户提交内容,获取用户信息
*/
onGotUserInfo: function(e) {
console.log("xxx1")
/**
* 检查评论内容是否为空
*/
if (!this.checkContent(this.data.content)) {
return;
}
/**
* 如果用户授权,则能拿到数据,否则就是用户拒绝授权,那么提示无法评论
*/
if (e.detail.userInfo) {
if (this.data.comorfeed == "评论文章") {
//发表评论
console.log(this.data.comorfeed)
allReq.userLogin(e.detail.userInfo.nickName, e.detail.userInfo.avatarUrl, e.detail.userInfo.gender, this.data.content, this.data.artilceId, 0);
} else {
console.log("回复评论")
console.log(this.data.id)
var co = this.data.content.split("[回复" + this.data.comment.commment[this.data.index].userName + "评论]:");
console.log(co)
allReq.userLogin(e.detail.userInfo.nickName, e.detail.userInfo.avatarUrl, e.detail.userInfo.gender, co[1], this.data.artilceId, this.data.id);
}
this.setData({
content: "",
id: "",
comorfeed: "评论文章",
insertorfeed: "发表",
})
} else {
remind.modal("提示", '让小每认识你之后才能评论哦')
}
},
其实实现聚焦不难,有API我们很容易实现,有点麻烦的是一系列的判断,因为既然用到了聚焦那么肯定不单单只是拉起键盘那么简单你最终要实现的东西肯定还需要进一步的推进,此时到底是用失焦还是想我一样就需要你分析你的需求了。