微信小程序公测也有段时间了,但是里面的坑踩了一个又一个,心也是够累的。本文说说关于 textarea 组件的 bug。(注:本文提及的 bug,至少在 2016-12-1日还存在)

上一篇:微信小程序之踩坑之旅一,wx.request 和 wx.uploadFile

测试时使用到:

  • 微信web开发者工具 v0.11.112301

  • 手机预览,iPhone6s,微信6.3.31

在日常的开发过程中,textarea 被使用到的频率还是挺高的,且很多情况需要用 Javascript 去控制它的一些行为,本文将举一个例子,去说说这个大家在开发中都可能会遇到的坑。

需求:清空 textarea 组件的内容。

需求是多么的简单,实现起来想想都觉得好简单(偷笑.jpg),有童鞋马上举手回答,提出了一个解决方案。

方案1

  • 搭配 form 组件使用

  • form 组件绑定 bindreset 事件

  • 添加一个 button 组件,指定 formType 为 reset

  • 需要重置时就点击一下这个 button

缺点

??的确,方案1是完全可以做到清空 textarea 组件,但却不够灵活。

  • 当一张表单有 n 个字段,而我偏偏只需要清空 textarea 组件内容时

  • 当使用场景没有一个重置的 button 组件时

  • 不知道你还想到其他什么缺点?

方案2

有童鞋又回答,可以使用数据绑定功能,将 textarea 组件的 value 属性绑定到一个数据属性,这样当要清空 textarea 组件的内容时,只需要对绑定的数据属性做空字符串值赋值操作即可。

??,上面这位童鞋说到点上了,和很多现在流行的 MVVM 框架一样(诸如 vue、ng1、ng2等),小程序也具备了数据绑定的功能(感动.jpg),那么下面就使用这种方式去完成这个如此简单的需求吧。
(吐槽:但对比那些框架,我觉得这个小程序的数据绑定功能用起来有点残废的感觉,可能被 vue 惯坏了)

对比图

方案已经说了,但既然说是踩坑之旅,那么肯定就没有方案所说的那么简单,没点坑就不像话了,下面会提供四张动图,都是根据方案2去处理的,请仔细对比。

在微信web开发工具时,所有实现方式:

你会看到:

  1. 方式1,清空不了 textarea 组件的内容

  2. 方式2,可以清空内容

  3. 方式3,可以清空内容

上面说到方式2和方式3都可以清空内容,那么为什么会有方式3这种“搞笑”的写法呢?因为方式2这种写法在手机预览时会有 bug,挺好笑的 bug,详细可以看第三、第四张运行图。

ondevtools.gif

在手机预览时,方式1:

跟在开发工具运行时的情况一样,也是清空不了。
1.gif

在手机预览时,方式2:

这就是的bug,清空是没问题的,但童鞋们可以留意一下 textarea 组件的 placeholder 的变化,清空之后,一时有一时没有,为了解决这个 bug,于是就有了方式3的写法。
2.gif

在手机预览时,方式3:

加了个 setTimeout,在300毫秒后再将绑定的属性设置为空字符串。
3.gif

看到这里,相信童鞋们都知道是怎么回事了,又是时候吐槽一下微信开发团队了,你丫快点修复这种莫名其妙的 bug!

代码

有人说不上代码不厚道,其实更想大家去我的仓库看,因为顺手就可以 star 一下,哈哈哈。

处理页面的js,test.js

Page({
  data: {
    inputContent: ''
  },
  clearInputContent(e) {
    const mode = parseInt(e.target.dataset.mode)

    switch (mode) {
      case 1:
        this.setData({
          inputContent: ''
        })
        break;
      case 2:
        this.setData({
          inputContent: ' '
        })
        this.setData({
          inputContent: ''
        })
        break;
      case 3:
        this.setData({
          inputContent: ' '
        })
        setTimeout(_ => {
          this.setData({
            inputContent: ''
          })
        }, 300)
        break;
    }
  }
})

页面UI,test.wxml

<view style="width: 90%; margin: 20rpx auto 0;">
    <text>textarea 组件 bug</text>
    <textarea placeholder="input content" value="{{inputContent}}" style="margin-top: 30rpx; border: 1rpx solid #ddd; width: 100%;"/>
    <text style="color: #999; font-size: 28rpx;">上面的 textarea 组件 绑定了 inputContent 属性</text>
</view>

<view style="width: 90%; margin: 50rpx auto 0;">
    <button bindtap="clearInputContent" data-mode="1">清空内容 方式1</button>
    <text style="color: #999; font-size: 28rpx;">方式1,执行 this.setData({inputContent: ''})</text>
</view>

<view style="width: 90%; margin: 50rpx auto 0;">
    <button bindtap="clearInputContent" data-mode="2">清空内容 方式2</button>
    <text style="color: #999; font-size: 28rpx;">方式2,
    执行 this.setData({inputContent: ' '})
    执行 this.setData({inputContent: ''})
    </text>
</view>

<view style="width: 90%; margin: 50rpx auto 0;">
    <button bindtap="clearInputContent" data-mode="3">清空内容 方式3</button>
    <text style="color: #999; font-size: 28rpx;">方式3,
    执行 this.setData({inputContent: ' '})
    执行 setTimeout(_ => { this.setData({inputContent: ''}) }, 300)
    </text>
</view>

mjw
584 声望19 粉丝