微信小程序踩坑 – 1: 输入框 + 按钮 事件绑定配合问题

1f7df3bada16a517f641a8ffd2a2ad2.png

每天一个知识点

最近在给公司的一个老微信小程序项目进行维护,本人以前也没怎么接触过小程序开发,大概看了看原来的代码就上手了。

很快,一天不到,就开发了一个像模像样的页面,主要交互部分就是这个【搜索框 + 搜索按钮】,很常见的功能逻辑。

image.png

问题发现

但是,很快哈,非常快,刚上线,就被测试逮到,提了一个问题:
第一次搜索不对,第二次搜索就对了。

1689563475552.png

我心想这什么鬼啊?仔细询问了下,得知,具体复现如下:

  1. 点击输入框,拉起手机键盘,输入关键字,如我们输入“国务院”。
  2. 此时直接点击查询按钮。
  3. 展现的结果没有变化,还是全部文章,并没有过滤。

问题解决探索

既然知道了稳定复现步骤,我直接打开【微信开发者工具】,进行复现。

But,没有复现啊~

image.png

我一度怀疑是收集问题,因为测试用的 iPhone 手机测试的,但是谨慎的我还是先使用自己的手机再来一次测试。

很奇怪的是,在反复几次测试下,我发现我的手机(Android)也会不定的出现这个问题。

使用开发者工具的真机调试,能够看到,出现无法过滤的问题情况下接口的请求字段没有更新:

name字段还是空的,而非我们输入的 "国务院"

e302edc59c1b46c54627fffba2dfa2b.png

基于此,我想到了是不是由于微信事件的触发顺序导致的?

一些热知识:

微信小程序原生语言下,实现数据双向绑定需要使用 事件监听 + this.setData({...}) (这一点与 React 类似)。

而我们的搜索输入框数据双向绑定事件使用了 bindblur 进行监听【这里起初是为了节约一点点性能来着】。

按钮则是使用了 bindtap 监听。

基于上述的知识,我分别在 bindblurbindtap 两个监听处理函数中进行 log,最终发现果然,当错误发生时, bindtap 的log 要先于 bindblur

就这样,我发现了为什么过滤无效的直接原因,但目前还有一个问题——“为什么时而行时而不行?”

反复复现测试

带着这个问题,我反复进行了复现,最终被我发现了一个很有趣的现象:

如下图,当在手机键盘不手动收起的情况下,直接点击查询按钮,就必定会触发这个事件顺序触发错误的问题

1689576691115.png

而当我们手动点击收起键盘,等键盘收起后(即输入框失焦后),再点击查询按钮,则没有问题一切正常。

破案了

就这样,最终的疑惑也解决了,根本原因就在于,小程序下bindblurbindtap的事件顺序是这样的:

点击输入框外的其他控件:

先触发被点击控件的 bindtap 事件 -> 再收起键盘 -> 再触发输入框的 bindblur 事件

想要解决这个问题也很简单,我们直接将 bindblur 替换成 bindinput 在每次输入的时候都进行同步就可以了

    <input bindinput="handleInput" />
    <view bindtap="search">搜索</view>

发散测试

在小程序上我们发现了这个问题,那么原生的 html + js 是否也会在移动端下存在这个问题呢?

我构造了一个小demo进行测试:

PC上显然是没问题的

image.png

使用手机试一下,也没有问题,按照我们预想的先 onbluronclick 触发了(即使触发onclick时,在UI上input还没失焦,但实际上 onblur 已经触发了,将数据同步了)

7db0c66ccebe3baa7e29318c3e82a2f.jpg

结论: 故此,可以得出结论,这个 blur 和 click/tap 的先后顺序问题,只有小程序上存在,H5不需要关心。而小程序请尽量使用 bindinput 来绑定 input

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYuzvFqP' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片