異常描述:html
點擊按鈕獲取用戶手機號碼,有的時候會出現點擊無反應或好久以後才彈出用戶受權獲取手機號碼的彈窗,這種狀況下,也會出現點擊穿透的問題(詳見:微信小程序開發——連續快速點擊按鈕調用小程序api返回後仍然自動從新調用的異常處理)小程序
異常解析:微信小程序
1. getPhoneNumber的使用:api
對於 getPhoneNumber(OBJECT) API,因爲小程序須要用戶主動觸發才能發起獲取手機號接口,因此該功能不禁 API 來調用,需用 <button>
組件的點擊來觸發(具體使用方法詳見 getPhoneNumber(OBJECT) )。服務器
1 <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"> </button>
對於使用方法,官方文檔是這麼說的:微信
須要將 <button> 組件 open-type 的值設置爲 getPhoneNumber,當用戶點擊並贊成以後,能夠經過 bindgetphonenumber 事件回調獲取到微信服務器返回的加密數據, 而後在第三方服務端結合 session_key 以及 app_id 進行解密獲取手機號。
2. getPhoneNumber函數的執行時間:網絡
由粗體部份內容可知 bindgetphonenumber 綁定的是 open-type 爲 getPhoneNumber 的按鈕觸發調用獲取用戶手機號API的回調事件事件,而非單擊事件。session
經驗證,從按鈕點擊到回調事件響應是有必定延遲的,並且會受網絡及微信服務器影響(回調事件開頭能夠寫個console.log(e),就能在開發這工具控制檯監控到這個延遲了)。app
若是網絡很是卡——那麼等微信服務器響應的時間可能就比較長了(iphone 6 plus,iphone7 plus比較明顯,延遲1000ms以上甚至無反應的感受)iphone
1 Page({ 2 getPhoneNumber: function(e) { 3 console.log(e.detail.errMsg) 4 console.log(e.detail.iv) 5 console.log(e.detail.encryptedData) 6 } 7 })
因此,即便你在 getPhoneNumber 方法中寫了loading的代碼,也只能等微信服務器響應以後才能生效了,這並不符合咱們的需求。那麼怎麼解決這個問題呢?
解決方法:
方法其實很簡單,真的很簡單——使用bindtap綁定一個單擊事件就能夠了。雖然這是一個特殊的按鈕,但本質上仍是一個按鈕的,單擊事件仍然是有的。
被官方文檔誤導了,一直強調getPhoneNumber 這個綁定的回調事件,且在取消、確認受權及獲取加密數據操做都是在這個事件中處理的,潛意識中已經覺得這就是這個特殊按鈕單擊事件了。
給getPhoneNumber 按鈕綁定一個單擊事件,以下:
<buttonopen-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" bindtap='showLoading'
style='background: url({{btnImg}}) top center no-repeat;background-size:cover;border:0px;color:#ffffff;' plain="true">獲取用戶手機號碼</button>
1 /** 2 * 獲取手機號碼單擊事件(在回調事件以前執行,預先顯示loading,防受權彈窗彈出延遲) 3 * loading使用自定義組件(小程序原生loading加載有延遲,沒法徹底防止點擊穿透) 4 */ 5 showLoading:function(){ 6 this.setData({ 7 loading: true 8 }) 9 }
如此,問題解決,在點擊按鈕的時候,就能及時顯示loading。
我的原創博客,轉載請註明來源地址:http://www.javashuo.com/article/p-ekkxmtnq-eh.html