微信小程序:物理返回鍵和navigateBack的細微區別


背景說明:在業務開發中存着這樣一個場景,點擊A頁面的“一級評論輸入框”會跳轉評論輸入頁面B,點擊A頁面的“他人評論”會彈起小輸入框和鍵盤。

存在問題:在跳轉進入B頁面后 textarea 輸入框會自動聚焦,彈起鍵盤,若不做任何操作直接點擊左上角“取消”按鈕返回A頁面,則到A頁面后,初次點擊“他人評論”時小輸入框會無法按預期效果跟隨着鍵盤一起彈起。第二次點擊才可以按照預期彈起。

發現問題關鍵:隨着多次測試發現,當進入B頁面后,輸入文字或手動點其他區域讓輸入框失焦,再返回A頁面,則A頁面不會出現前述bug。所以將解決問題的關鍵鎖定在如何手動將B頁面中 textarea 輸入框失焦。

解決問題

首先眾所周知的是微信小程序沒有DOM這種說法,所以想像web開發中,使用DOM節點自動失焦是不可行的。於是經過查閱文檔以后,發現 textarea 存在一個屬性 focus,可以通過切換 focus 屬性實現聚焦與失焦的效果。

於是在data中定義的 focusFlag 用於控制 focus 的屬性值,初始值為 true,在退出當前頁面的 onUnload 生命周期里調用 setData,將 focusFlag 置為 false。然后用我的 Android 老爺機測試了一下,乍一看沒什么問題。

···
onUnload () {
   this.setData({
       focusFlag: false
   })
}
···

正當以為問題解決了的時候,換了一個酷炫 iPhone 11 來掃碼測試了一下,發現問題依然存在,還是不能彈起輸入框。並且特別奇怪的是,使用小程序左上角的物理返回鍵時,一切正常,但是使用左上角的 “取消” 按鈕進行返回時,就不行了,怎么會呢??

“取消” 按鈕綁定的事件里也設置了setData,將 focusFlag 置為 false ,然后再調用 wx.navigateBack() 啊,有什么問題嗎?怎么物理返回鍵就行,我手動調用 wx.navigateBack() 就不行呢?小丫頭片子還兩幅面孔呢?

就在我和同事冥思苦想的時候,突然靈光一閃。是不是 使用 wx.navigateBack() 進行返回頁面時不會經過 onUnload 生命周期呢?事實證明我在想屁吃, wx.navigateBack() 一樣會經過 onUnload 生命周期。那這是為什么呢?陷入了僵局。

於是我再想,我的 Android 老爺機測試沒有問題,而 ios 年輕力壯機就不行,這倆除了操作系統不同以外,還有就是運行速度不一致,一個快的飛起,一個慢的一批,是不是系統在處理數據時因為運行環境快慢不同,導致對數據狀態的處理完整度上有問題?(我瞎猜的)再進一步想,是不是物理返回鍵和手動調用 wx.navigateBack() 還真是有細微不同,可能點擊物理返回鍵時系統會對頁面狀態清理的更加徹底,但是使用 wx.navigateBack() 時可能就會存在狀態殘留,為了爭取盡快進入下一個頁面的渲染,把上一個頁面的渲染狀態到一半就結束了,沒完成就算了,反正影響不大,畢竟頁面之間是隔離開來的。

於是就再次查找文檔,最終發現了解決問題的最終方法:setData 的成功回調函數!你不是要盡快進入下一個頁面的渲染嗎?我偏要讓你完成我的狀態渲染以后才能跑!代碼如下:

this.setData({
   focusFlag: false
}, () => {
   wx.navigateBack(); 
})

⑧ 到了這一步,問題就徹底解決了。使用的解決辦法非常簡單,就是很多人常用到會忽略的 setData 的回調函數,但是難點在想清楚整個 bug 出現的原因,定位錯誤,最終選擇最優的解決方案。

記錄bug,完結撒花。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM