本文轉自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
和compositionend
。get
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