前端怎么監(jiān)聽手機鍵盤是否彈起
作者:超神熊貓
原文:https://juejin.cn/post/7117814358259793933
在移動端開發(fā)經(jīng)常會遇到一些交互需要通過判斷手機鍵盤是否被喚起來做的,說到判斷手機鍵盤彈起和收起,有遇到過的同學,應該都知道,安卓和ios判斷手機鍵盤是否彈起的寫法是有所不同的
-
IOS端可以通過 focusinfocusout這兩個事件來監(jiān)聽
window.addEventListener('focusin', () => {
// 鍵盤彈出事件處理
alert("ios鍵盤彈出事件處理")
});
window.addEventListener('focusout', () => {
// 鍵盤收起事件處理
alert("ios鍵盤收起事件處理")
})
-
安卓只能通過 resize來判斷屏幕大小是否發(fā)生變化來判斷
由于某些 Android 手機收起鍵盤,輸入框不會失去焦點,所以不能通過聚焦和失焦事件來判斷。但由于窗口會變化,所以可以通過監(jiān)聽窗口高度的變化來間接監(jiān)聽鍵盤的彈起與收回。
const innerHeight = window.innerHeight
window.addEventListener('resize', () => {
const newInnerHeight = window.innerHeight;
if (innerHeight > newInnerHeight) {
// 鍵盤彈出事件處理
alert("android 鍵盤彈出事件");
} else {
// 鍵盤收起事件處理
alert("android 鍵盤收起事件處理")
}
})
-
因為ios和安卓的處理不一樣,所以還需要判斷系統(tǒng)的代碼
const ua = typeof window === 'object' ? window.navigator.userAgent : '';
let _isIOS = -1;
let _isAndroid = -1;
export function isIOS() {
if (_isIOS === -1) {
_isIOS = /iPhone|iPod|iPad/i.test(ua) ? 1 : 0;
}
return _isIOS === 1;
}
export function isAndroid() {
if (_isAndroid === -1) {
_isAndroid = /Android/i.test(ua) ? 1 : 0;
}
return _isAndroid === 1;
}
使用
<template>
<form class="keyboard-box" v-keyboard:keyboardFn>
<!-- 輸入任意文本 -->
<van-field v-model="text" label="文本" />
<!-- 輸入手機號,調(diào)起手機號鍵盤 -->
<van-field v-model="tel" type="tel" label="手機號" />
<!-- 允許輸入正整數(shù),調(diào)起純數(shù)字鍵盤 -->
<van-field v-model="digit" type="digit" label="整數(shù)" />
<!-- 允許輸入數(shù)字,調(diào)起帶符號的純數(shù)字鍵盤 -->
<van-field v-model="number" type="number" label="數(shù)字" />
<van-field v-model="textarea" type="textarea" label="textarea" />
<!-- 輸入密碼 -->
<van-field v-model="password" type="password" label="密碼" />
<van-radio-group v-model="radio" direction="horizontal" class="radio-group">
<van-radio name="1">單選框 1</van-radio>
<van-radio name="2">單選框 2</van-radio>
</van-radio-group>
</form>
</template>
<script>
import keyboard from './keyboard'
export default {
directives: { keyboard },
data() {
return {
text: '',
tel: '',
digit: '',
number: '',
password: '',
textarea: '',
radio: '1'
}
},
methods: {
keyboardFn(val) {
this.$toast(val ? '鍵盤彈起來了' : '鍵盤收起了')
}
}
}
</script>
問題
-
復選框、單選框的點擊也會導致
focusin和focusout的觸發(fā),我們需要處理一下,使其點擊復選框、單選框這類標簽的時候不觸發(fā)我們的回調(diào)函數(shù)// 主要是通過判斷一下當前被focus的dom類型
// document.activeElement.tagName
// tagName為輸入框的時候才算觸發(fā)鍵盤彈起
const activeDom = document.activeElement.tagName
if(!['INPUT', 'TEXTAREA'].includes(activeDom)) {
console.log('只有')
} -
當有橫屏功能的時候,
resize也會被觸發(fā)
增加寬度是否有改變的判斷,沒有改變,才是真正的鍵盤彈起//初始化的時候獲取一次原始寬度
const originWidth = document.documentElement.clientWidth || document.body.clientWidth
//結合處理復選框、單選框的點擊也會導致`focusin` 和`focusout` 的觸發(fā)問題的完整回調(diào)寫法
function callbackHook(cb) {
const resizeWeight = document.documentElement.clientWidth || document.body.clientWidth
const activeDom = document.activeElement.tagName
if(resizeWeight !== originWidth || !['INPUT', 'TEXTAREA'].includes(activeDom)) {
return isFocus = false
}
cb && cb()
} -
怎么傳入回調(diào)函數(shù),靈活使用
v-指定: fn 傳入函數(shù),在指令里面通過執(zhí)行回調(diào)的時候傳出參數(shù),來區(qū)分是鍵盤彈起還是收起//綁定指令的同時傳入回調(diào)函數(shù)
v-keyboard:keyboardFn
methods: {
keyboardFn(val) {
//val true 鍵盤彈起 false 鍵盤收起
this.$toast(val ? '鍵盤彈起來了' : '鍵盤收起了')
}
}
建議
使用應當要注意銷毀,也需要盡量減少綁定指令的次數(shù),一般在form表單上綁定一個,即可監(jiān)聽這個表單下的所有輸入框是否觸發(fā)手機鍵盤喚起了
最后
如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我個小忙:
點個「喜歡」或「在看」,讓更多的人也能看到這篇內(nèi)容
我組建了個氛圍非常好的前端群,里面有很多前端小伙伴,歡迎加我微信「sherlocked_93」拉你加群,一起交流和學習
關注公眾號「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時聊騷。
評論
圖片
表情
