最近專案中引用了Telerik ASP.NET擴充元件AutoComplete輸入欄位,測試時發現偶爾會不聽始喚,輸入文字時無法觸發資料查詢,在Javascript Source Code裡反覆追蹤測試,燃燒了可觀的寶貴春青,終於理出頭緒: 問題在中文輸入法!
過去模糊地知道中文輸入在瀏覽器的鍵盤事件行為上有些特殊,但從未深究,這回算是比較清楚研究其中的差別。其實最明顯的差異是: 切到中文輸入法後,輸入文字將不會觸發KeyPress事件,只會有KeyDown,而且傳回的e.keyCode會一律是229。
寫了一段程式來做實驗:
|
jQuery - 中文輸入法與KeyDown/KeyPress事件
最近專案中引用了Telerik ASP.NET擴充元件AutoComplete輸入欄位,測試時發現偶爾會不聽始喚,輸入文字時無法觸發資料查詢,在Javascript Source Code裡反覆追蹤測試,燃燒了可觀的寶貴春青,終於理出頭緒: 問題在中文輸入法!
過去模糊地知道中文輸入在瀏覽器的鍵盤事件行為上有些特殊,但從未深究,這回算是比較清楚研究其中的差別。其實最明顯的差異是: 切到中文輸入法後,輸入文字將不會觸發KeyPress事件,只會有KeyDown,而且傳回的e.keyCode會一律是229。
寫了一段程式來做實驗:
排版顯示純文字複製文字
我使用倉頡輸入法(New ChangJie 2010),以IE9測試,操作過程及結果如下:
- 切換到新倉頡輸入法,點txtTest取得焦點準備輸入文字
- 按【一】(M鍵),出現KeyDown: 229
- 按Enter鍵確定選字,此時出現Input!
- 按數字1,出現KeyDown: 229跟Input!
- 使用滑鼠將輸入法切回英文(不用按鍵切換避免觸發多餘事件)
- 按數字2,出現KeyDown: 50、KeyPress: 50以及Input!
FireFox4測試的結果與IE9相同。若將IE9切成IE7相容模式,結果不太相同,看來並不支援Input事件
- 切換到新倉頡輸入法,點txtTest取得焦點準備輸入文字
- 按【一】(M鍵),出現KeyDown: 229
- 按空白鍵選字,再出現KeyDown: 229
- 按數字1,出現KeyDown: 229
- 使用滑鼠將輸入法切回英文(不用按鍵切換避免觸發多餘事件)
- 按數字2,出現KeyDown: 50、KeyPress: 50
Chrome10的測試結果為:
- 切換到新倉頡輸入法,點txtTest取得焦點準備輸入文字
- 按【一】(M鍵),出現KeyDown: 229跟Input!
- 按空白鍵選字,出現KeyDown: 229跟Input!
- 按數字1,出現KeyDown: 229跟Input!
- 使用滑鼠將輸入法切回英文(不用按鍵切換避免觸發多餘事件)
- 按數字2,出現KeyDown: 50、KeyPress: 50以及Input!
胡亂做個結論:
輸入欄位啟用中文輸入法時,將不會觸發KeyPress事件,而KeyDown事件中的 KeyCode則固定傳回229。IE9, Firefox 4, Chrome支援按鍵Input事件,在IE9/Firefox4上可輔助判別中文輸入的細節,但IE7不支援,Chrome的行為不同。
綜合以上觀察,要自己搞出跨瀏覽器可以精準在使用者輸入每個字(不管有輸入法、不管中英文)時觸發的事件,看來是很艱鉅的任務。所幸網路上善心神人很多,找到一個不錯的解法, Cross browser input event for jQuery, 這個Plugin重新包裝了input事件,所以我們只需寫成:
$("#txtText").bind("input", function() {
this.value; //可取得目前的文字內容
});
就能在每次輸入中文字或英文字時觸發input事件,雖然無法精確掌握每次的按鍵內容,但已可滿足掌握中文輸入模式下每次文字變動的需求。[2011-04-26補充]要精確抓取每一個按鍵的keyCode,可考慮使用KeyUp事件(但連選字時的上下鍵,送字的Space都包含在內),感謝drem補充!
為網路開發者社群按一個讚!