compositionstart 和 compositionend 事件解決中文輸入法截斷問題

本文轉自https://zhuanlan.zhihu.com/p/26141351餓了麼大神文章節選code

在 Web 開發中,常常要對錶單元素的輸入進行限制,好比說不容許輸入特殊字符,標點。一般咱們會監聽 input 事件:事件

inputElement.addEventListener('input', function(event) {
  let regex = /[^1-9a-zA-Z]/g;
  event.target.value = event.target.value.replace(regex, '');
  event.returnValue = false
});

這段代碼在 Android 上是沒有問題的,可是在 iOS 中,input 事件會截斷非直接輸入,什麼是非直接輸入呢,在咱們輸入漢字的時候,好比說「喜茶」,中間過程當中會輸入拼音,每次輸入一個字母都會觸發 input 事件,然而在沒有點選候選字或者點擊「選定」按鈕前,都屬於非直接輸入。開發

這顯然不是咱們想要的結果,咱們但願在直接輸入以後才觸發 input 事件,這就須要引出我要說的兩個事件—— compositionstart compositionendget

compositionstart 事件在用戶開始進行非直接輸入的時候觸發,而在非直接輸入結束,也即用戶點選候選詞或者點擊「選定」按鈕以後,會觸發 compositionend 事件。input

var inputLock = false;
function do(inputElement) {
    var regex = /[^1-9a-zA-Z]/g;
    inputElement.value = inputElement.value.replace(regex, '');
}

inputElement.addEventListener('compositionstart', function() {
  inputLock = true;
});


inputElement.addEventListener('compositionend', function(event) {
  inputLock = false;
  do(event.target);
})


inputElement.addEventListener('input', function(event) {
  if (!inputLock) {
    do(event.target);
    event.returnValue = false;
  }
});

添加一個 inputLock 變量,當用戶未完成直接輸入前,inputLock 爲 true,不觸發 input 事件中的邏輯,當用戶完成有效輸入以後,inputLock 設置爲 false,觸發 input 事件的邏輯。這裏須要注意的一點是,compositionend 事件是在 input 事件後觸發的,因此在 compositionend事件觸發時,也要調用 input 事件處理邏輯。it

相關文章
相關標籤/搜索