解决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

相关文章
相关标签/搜索