1. 程式人生 > >微信小程式之踩坑textarea 元件的 bug

微信小程式之踩坑textarea 元件的 bug

微信小程式公測也有段時間了,但是裡面的坑踩了一個又一個,心也是夠累的。本文說說關於 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>