問題描述:
監聽文本輸入框的input事件,在拼寫漢字(輸入法)但漢字並未實際填充到文本框中(選詞)時會觸發input事件,如圖:

需求:選詞完成后觸發input事件,只觸發一次。
解決辦法:
通過查閱資料得知在輸入中文(包括語音識別時)會先后觸發compositionstart、compositionend事件,類似於keydown和keyup的組合。
觸發compositionstart時,文本框會填入 “虛擬文本”(待確認文本),同時觸發input事件;在觸發compositionend時,就是填入實際內容后(已確認文本)。
先看看 compositionstart 的描述 和 compositionend 的 描述
compositionstart 事件觸發於一段文字的輸入之前(類似於 keydown 事件,但是該事件僅在若干可見字符的輸入之前,而這些可見字符的輸入可能需要一連串的鍵盤操作、語音識別或者點擊輸入法的備選詞)。
compositionend 當文本段落的組織已經完成或取消時,會觸發該事件。
個人理解:
compositionstart 在輸入一段需要確認的文本如拼音to漢字、語音時會觸發
compositionend 在拼音選詞完成、語音輸入完畢時會觸發
至此,思路get: 聲明一個標記flag,在compositionstart、compositionend兩個事件過程之間的時候flag值為false,在input事件中通過flag的值來判斷當前輸入的狀態。
OK,接下來貼出示例代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="http://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>
<title></title>
</head>
<body>
<input id="txt" type="text">
<script>
var flag = true;
$('#txt').on('compositionstart',function(){
flag = false;
})
$('#txt').on('compositionend',function(){
flag = true;
})
$('#txt').on('input',function(){
var _this = this;
setTimeout(function(){
if(flag){
console.log($(_this).val());
}
},0)
})
</script>
</body>
</html>
效果圖:

tips:
為什么使用延時器?
因為選詞結束的時候input會比compositionend先一步觸發,此時flag還未調整為true,所以不能觸發到console,故用setTimeout將其優先級滯后。
