1.環(huán)境
語(yǔ)言:vue
輸入法:微軟輸入法
2.場(chǎng)景舉例
采用指令方式實(shí)現(xiàn)一個(gè)只允許輸入中午的輸入框。但是在使用微軟輸入法時(shí),由于輸入漢字的時(shí)候在未輸入完成的時(shí)候輸入法已經(jīng)把拼音輸入到input中贰逾,這樣就會(huì)觸發(fā)我們指令邏輯導(dǎo)致拼音被清除审残,所以導(dǎo)致無(wú)法輸入先紫。
3.解決思路
使用輸入框事件compositionstart和compositionend監(jiān)聽(tīng)是否開(kāi)啟新的輸入或者結(jié)束本次輸入衩茸,如果開(kāi)啟新的輸入就不允許更新,如果結(jié)束輸入就允許更新
事件說(shuō)明:
compositionstart
文本合成系統(tǒng)如 input method editor(即輸入法編輯器)開(kāi)始新的輸入合成時(shí)會(huì)觸發(fā) compositionstart 事件藐窄。
例如资昧,當(dāng)用戶(hù)使用拼音輸入法開(kāi)始輸入漢字時(shí),這個(gè)事件就會(huì)被觸發(fā)荆忍。
compositionend
當(dāng)文本段落的組成完成或取消時(shí)格带,compositionend 事件將被觸發(fā) (具有特殊字符的觸發(fā),需要一系列鍵和其他輸入刹枉,如語(yǔ)音識(shí)別或移動(dòng)中的字詞建議)叽唱。
4.案例
Vue.directive('limitInput', ()=>{
? /* 兼容性檢測(cè)
? ? chrome:oncompositionstart--->oninput--->oncompositionend
? ? firefox: oncompositionstart--->oncompositionend--->oninput */
? /* 限制輸入中文+空格/英文+空格/數(shù)字+空格/保留 binding.value 位小數(shù) */
? bind(el, binding) {
? ? const arg = binding.arg
? ? // 限制規(guī)則
? ? const restrictRule = {
? ? ? zh: /[^\s\u4E00-\u9FA5\s]/g, // 中文
? ? ? en: /[^a-zA-Z\s]/g, // 英文
? ? ? number: /[^0-9]/g, // 純數(shù)字
? ? ? float: (val) => {
? ? ? ? // 保留 v-limitInput:float="n" n位小數(shù)數(shù)字
? ? ? ? val =
? ? ? ? ? val.indexOf('.') > -1
? ? ? ? ? ? ? val.slice(0, val.indexOf('.') + binding.value + 1)
? ? ? ? ? ? : val
? ? ? ? return val.replace(/[^0-9\.]/g, '')
? ? ? }
? ? }
? ? const multiValitor = ['float'] // 多重限制類(lèi)型
? ? const restrict = restrictRule[binding.arg]
? ? let inputLock = false // 輸入鎖 使用輸入法時(shí)關(guān)閉限制 結(jié)束輸入法輸入時(shí)觸發(fā)限制
? ? const doRule = (e) => {
? ? ? // 判斷是否多重校驗(yàn)形式
? ? ? if (multiValitor.indexOf(arg) === -1) {
? ? ? ? e.target.value = e.target.value.replace(restrict, '')
? ? ? } else {
? ? ? ? e.target.value = restrictRule[arg](e.target.value)
? ? ? }
? ? ? // 手動(dòng)更新綁定值
? ? ? e.target.dispatchEvent(new Event('input'))
? ? }
? ? const target =
? ? ? el instanceof HTMLInputElement ? el : el.querySelector('input')
? ? target.addEventListener('input', (event) => {
? ? ? /*
? ? ? ? 若不是手動(dòng)輸入(inputType === 'insertText'),是更新時(shí)觸發(fā)此事件則不再執(zhí)行校驗(yàn)
? ? ? ? 防 dispatchEvent 無(wú)限觸發(fā)限制校驗(yàn)
? ? ? */
? ? ? if (!inputLock && event.inputType === 'insertText') {
? ? ? ? doRule(event)
? ? ? ? event.returnValue = false
? ? ? }
? ? ? event.returnValue = false
? ? })
? ? /* 使用輸入法開(kāi)始觸發(fā) */
? ? target.addEventListener('compositionstart', (event) => {
? ? ? inputLock = true
? ? })
? ? /* 結(jié)束輸入法使用觸發(fā) */
? ? target.addEventListener('compositionend', (event) => {
? ? ? inputLock = false
? ? ? doRule(event)
? ? })
? }
}
)
案例基于:https://juejin.cn/post/7081088003531079687?searchId=20240506174617A2F6C79CB31095069E68