input事件中文觸發多次問題研究


轉自:https://blog.csdn.net/weixin_34198797/article/details/88906273

我們在網頁中經常會遇到實時搜索的情況,或者其他類似需要input實時響應的問題,一般情況下,我們是利用input和propertychange事件來監聽input內容的變化來響應,但是有一個問題就是當輸入漢字的時候,可能我們要輸入 ‘實時’ 的時候,我們的input框中會出現 'shishi'直到我們的空格才會變成 '實時',這也就意味着我們依次響應了 's','sh','shi','shis','shish','shishi','實時',前面的結果明顯不是我們需要的 ,造成了我們很多次無用的提交,如果是接口請求,那更要命,多發了好多次請求。

  最早之前有一個稍微能改善的解決方案就是配合一個定時器延時執行,這樣能減少請求次數,但是這個減少是不分情況的減少 ,還是治標不治本。

  今天偶然看到幾個事件,發現可以完美解決這種問題。我們來看一下這幾個事件

  compositionstart , compositionupdate ,compositionend  

  compositionstart 官方解釋 : 觸發於一段文字的輸入之前(類似於 keydown 事件,但是該事件僅在若干可見字符的輸入之前,而這些可見字符的輸入可能需要一連串的鍵盤操作、語音識別或者點擊輸入法的備選詞),通俗點,假如我們要輸入一段中文,當我們按下第一個字母的時候觸發 。

  相應的compositionupdate在我們中文開始輸入到結束完成的每一次keyup觸發。

  而compositionend則在我們完成當前中文的輸入觸發 。

  正題來了,通過上面的事件我們就可以完美的解決中文輸入的響應問題了,從compositionstart觸發開始,意味着中文輸入的開始且還沒完成,所以此時我們不需要做出響應,在compositionend觸發時,表示中文輸入完成,這時我們可以做相應事件的處理。

  所以我們可以設置一個變量,或者給input定義一個屬性,在compositionstart到compositionend之間對input事件不做出響應。看以下代碼 

$('input').on({ 
    input : function(e){ 
        var flag = e.target.isNeedPrevent; 
        if(flag) return; 
        response() 
    }, 
    compositionstart : function(e){ 
        e.target.isNeedPrevent = true ; 
    }, 
    compositionend : function(e){ 
        e.target.isNeedPrevent = false; 
    } 
})
 
function response(){ 
    $('div').append('<p>事 件觸發</p>') 
}

 

我們通過compositionstart,compositionend事件來設置flag,判斷是否正在進行輸入中文以控制input事件的響應,看上去沒有問題,但實際執行時會發現在谷歌瀏覽器中input執行順序要先於compositionend,火狐執行順序正常,但compositionend會響應兩次。這就導致谷歌瀏覽器中輸入漢字不會響應input事件。當然也可以在compositionend事件中再執行一次response事件,這樣的問題是在火狐瀏覽器中會多執行一次response,顯然不是最優方案。

  經過試驗,發現keyup和compositionend事件執行順序在各大瀏覽器都保持一致,於是我們改成如下代碼:

$('input').on({ 
    keyup : function(e){ 
        var flag = e.target.isNeedPrevent; 
        if(flag) return; 
        response() 
    }, 
    compositionstart : function(e){ 
        e.target.isNeedPrevent = true ; 
    }, 
    compositionend : function(e){ 
        e.target.isNeedPrevent = false; 
    } 
})
 
function response(){ 
    $('div').append('<p>事 件觸發</p>') 
}

 

這樣在各個瀏覽器基本保持一致了(兼容compositionstart的瀏覽器)。但是keyup有一個問題,比如通過鼠標復制粘貼的時候並不相應keyup事件,所以上面的事情我們還需要再優化下,keyup相應按鍵事件,input響應除了keyup之外的變化事件。代碼如下

$('input').on({ 
    keyup : function(e){ 
        var flag = e.target.isNeedPrevent; 
        if(flag) return; 
        response() ; 
        e.target.keyEvent = false ; 
    }, 
    keydown : function(e){ 
        e.target.keyEvent = true ; 
    }, 
    input : function(e){ 
        if(!e.target.keyEvent){ 
            response() 
        } 
    }, 
    compositionstart : function(e){ 
        e.target.isNeedPrevent = true ; 
    }, 
    compositionend : function(e){ 
        e.target.isNeedPrevent = false; 
    } 
})
 
function response(){ 
    $('div').append('<p>事 件觸發</p>') 
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM