解決oninput事件在中文輸入法下會取得拼音的值的問題

在作搜索等功能時,不少時候咱們須要實時獲取用戶輸入的值,而經常會獲得相似 w'm 這樣的拼音。爲了解決這個問題,我在網上搜索了下相關問題,發現了兩個陌生的事件:compositionstartcompositionendjavascript

compositionstart & compositionend

MDN 上找到了關於他們的描述,compositionstartcompositionend。簡單點描述以下:java

  • compositionstart:在輸入中文或者語音等須要等待一連串的輸入的操做以前,compositionstart 事件會觸發。
  • compositionend:在輸入中文或者語音等完畢或取消時,compositionend 事件會觸發。

input 和 compositionend 的觸發順序致使的問題

注:如下爲 chrome 瀏覽器下的測試結果,關於其餘瀏覽器請看兼容說明!git

和大多數人的想法同樣,我考慮使用一個布爾值來判斷是否在等待輸入法的輸入,而後在 input 事件中根據其布爾值決定是否獲取輸入的值,初始代碼以下:github

var isInputZh = false;
  
elem.addEventListener('compositionstart', function (e) {
  isInputZh = true;
}, false);
elem.addEventListener('compositionend', function (e) {
  isInputZh = false;
}, false);
elem.addEventListener('input', function (e) {
  if (isInputZh) return;
  var value = this.value;
  console.log(value);
  doSomething(value);
}, false);

嗯。。看起來好像沒啥問題,運行後,卻有些讓人摸不着頭腦。在一段中文輸入完畢後卻並無在控制檯輸出任何數據。嗯。。測試後發現 compositionend 事件是在 input 事件以後觸發的。chrome

解決方法

最後只能用常規方法去解決:在 compositionendinput 事件中都得加入對輸入值的處理。代碼以下:瀏覽器

var isInputZh = false;
var search = document.querySelector('input');

search.addEventListener('compositionstart', function (e) {
  isInputZh = true;
}, false);
search.addEventListener('compositionend', function (e) {
  isInputZh = false;

  doSomething(search.value);
}, false);
search.addEventListener('input', function (e) {
  if (isInputZh) return;
  var value = this.value;

  doSomething(value);
}, false);

關於兼容說明

以上測試是在 chrome 瀏覽器下進行的,在 FirefoxEdge 瀏覽器下發現 input 事件在 compositionend 事件以後觸發,且在輸入數字時發現 FirefoxEdge 也會觸發 compositionend 事件,以上內容僅在 chrome 瀏覽器中適用。測試

寫在最後

原文發在 github。若是你們有什麼好的解決方案歡迎在評論中提出。this

相關文章
相關標籤/搜索