最近做的一個小程序需求,其中一個頁面使用到了 textarea這個小程序組件,然后點擊頁面上的某個元素,會觸發頁面彈起一個彈窗,這時發現 textarea的 placeholder文字或者輸入的文字內容,會直接穿透遮罩層和浮動彈窗,顯示在最上面,開始時我以為是遮罩層和浮動彈窗的層級舍得小了,于是改大,誰知道沒用,改到了 99999也沒用,于是我意識到這應該不是我代碼的問題,網上一搜,果然有故事。
這是最簡單的解決手段,一般彈窗的時候,都會帶個遮罩層,把遮罩層下面的內容隱藏一部分,用戶基本上不會注意的,然后再去掉彈窗和遮罩層的時候再把 textarea顯示出來。 這種方法簡單有效,大部分情況下都可以這么解決。
<textarea wx:if="{{ showMask }}">textarea> 復制代碼
有時候, textarea穿透的不是遮罩層,或者遮罩層以一種半透明而非完全遮住頁面內容的形式呈現,擔心用戶能夠看到因為 textarea的消失而導致頁面跳動,產生不好的用戶體驗,那么就可以使用替代元素來替代 textarea而非將之直接隱藏掉。
基本的 textarea組件只接受文本的輸入,拋開可輸入性的話,外觀上看就是一個含有文本節點的簡單元素,只需要獲取當前狀態下的 textarea中輸入的文字,將之賦予給一個樣式與 textarea相同的普通元素,就達到了臨時替代的效果。
<textarea id="text-area" value="{{txtRealContent}}" bindinput='txtInput' wx:if="{{!showMask}}" /> <view class='rich-text' style="{{('height:' + txtHeight + 'px')}}" wx:else> <rich-text nodes="{{txtRealContent}}">rich-text> view> 復制代碼
如上所示
上面四個步驟,都比較簡單,稍微需要注意的是,如果 textarea的內容包含了換行文本,則需要對換行符進行處理:
textareaContent.replace(/\n/g, ' ') 復制代碼
如果你想讓 textarea自動增加高度而不是固定高度,給 textarea加了個 auto-height,那么就需要“實時”獲取其高度 說是 “實時”,其實也并不是那么實時,不考慮其他樣式的變化, textarea的高度與行數有關,每增減一行,其高度才會變化,所以只需要監控其內容行數的變化即可,恰好 textarea組件也已經提供了這個監控器:bindlinechange。
原理說完了,完整實例代碼如下:
index.wxml
<view class="page-body"> <button bindtap="changeMaskVisible">切換maskbutton> <view class="textarea-wrp"> <textarea id="text-area" value="{{txtContent}}" bindinput='txtInput' bindlinechange="textAreaLineChange" wx:if="{{!showMask}}" auto-height /> <view class='rich-text' style="{{('height:' + txtHeight + 'px')}}" wx:else> <rich-text nodes="{{txtRealContent}}">rich-text> view> view> <button>Footerbutton> <view wx:if="{{showMask}}" bindtap="changeMaskVisible" class="mask"> <view class="mask-content">view> view> view> 復制代碼
index.js
Page({ data: { txtRealContent: '', txtContent: '', showMask: false, txtHeight: 0 }, textAreaLineChange(e) { this.setData({ txtHeight: e.detail.height }) }, txtInput(e) { this.setData({ txtContent: e.detail.value }) }, changeMaskVisible(e) { if (!this.data.showMask) { // 將換行符轉換為wxml可識別的換行元素 const txtRealContent = this.data.txtContent.replace(/\n/g, ' ') this.setData({ txtRealContent }) } this.setData({ showMask: !this.data.showMask }) } }) 復制代碼
index.wxss
.rich-text { overflow: hidden; } .mask { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 0, 0, .6); z-index: 10; } .mask-content { position: fixed; top: 44%; left: 50%; height: 60%; width: 60%; transform: translate(-50%, -50%); background-color: yellowgreen; z-index: 12; }