1、項目背景:vue項目,手機加短信驗證碼登錄;
2、問題: 在ios中input吊起軟鍵盤,輸入完成后,收起軟件盤,頁面不會回彈,導致頁面下方出現空白,也就是頁面變形;
3、最開始的解決方案是,用input的失去焦點事件@focusout,在input失去焦點的時候讓頁面回滾到頂部,具體代碼如下:
// 首先,判斷觸發事件的目標元素是否是input輸入框,我們只關注輸入框的行為。 if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { window.scrollTo(0, 0) }
這樣可以解決頁面變形問題,但是切換input的時候,會出現頁面先滾動然后又回到光標位置,就是頁面先執行了失去焦點事件,回到頂部,然后input又獲取焦點,重新回到當前位置;
表現形式如下:
4、最終優化方案是:用定時器延時執行@focusout,在添加一個@focusin事件;
如果是input切換,則直接取消定時器,不在執行回到頂部的代碼,這樣頁面就不會回滾;
如果時輸入完成,則延時20ms后再回到頁面頂部,這樣完美解決該問題;
具體代碼如下:
<div class="login" v-if="isLogin" @focusout="handleInputBlur" @focusin="handleInputBin"> <div> <input class="phone" v-model="phone" type="number" placeholder="請輸入"> </div> <div class="sms-body"> <div> <input class="sms" type="number" placeholder="請輸入"> </div> <div> <button class="smsBtn" v-if='sendAuthCode' @click="handleGetSms">{{smsBtn}}</button> <button class="timeBtn" v-else >{{smsBtn}}</button> </div> </div> <div> <button class="post-phone-btn" @click="handlePostBtn">綁定</button> </div> </div>
// 針對ios鍵盤導致頁面變形的處理----冒泡獲取所有失去焦點事件 // 將獲得失去焦點時間延時執行,如果再重新獲取焦點則清除定時器,不將頁面回滾到頂部,避免出現頁面來回滾動的情況 // 如果輸入完成之后,沒有在重新獲取焦點,則延時20ms后再將頁面回彈到頂部 handleInputBlur (e) { if (this.timer) { clearTimeout(this.timer) } // 首先,判斷觸發事件的目標元素是否是input輸入框,我們只關注輸入框的行為。 if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { this.timer = setTimeout(() => { window.scrollTo(0, 0) }, 20) } }, // 獲得焦點事件 handleInputBin (e) { if (this.timer) { clearTimeout(this.timer) } }