摘要:一需求闡述和常用的解決方案制作一個文本框限制最大字數,實時監聽當前已經輸入的字數,并顯示出來。因此單純的監聽事件顯示是不夠的。如果頁面里需要多個文本框都要限制字數如何實現。
一、需求闡述和常用的解決方案
制作一個文本框限制最大字數,實時監聽當前已經輸入的字數,并顯示出來。期初我實現這個功能的方法很簡單:給textarea控件添加onkeyup事件方法,在方法中將textarea值的長度打印出來,并給textarea添加一個maxlength屬性設置長度限制即可。代碼如下:
0/10
var txt0 = document.getElementById("txt0"); var txtNum0 = document.getElementById("txtNum0"); txt0.addEventListener("keyup",function(){ txtNum0.textContent = txt0.value.length; });二、存在的問題
這樣貌似很簡單就實現了,在英文輸入法下一切還都ok,但當我們用輸入法輸入中文時,問題很快就來了,比如我們要輸入“文章”一詞就要輸入“wenzhang”瀏覽器會監聽到8詞keyup事件。在一些瀏覽器(如safari)中,如果這個過程超過maxlength甚至會阻止你繼續輸入。因此單純的監聽keyup事件顯示是不夠的。
每次按下鍵盤就會觸發監聽事件
經過查閱前輩們的解決方案,發現了兩個之前沒有聽說過的屬性“compositionstart”和“compositionend”。
MDN上的解釋:compositionstart 事件觸發于一段文字的輸入之前(類似于 keydown 事件,但是該事件僅在若干可見字符的輸入之前,而這些可見字符的輸入可能需要一連串的鍵盤操作、語音識別或者點擊輸入法的備選詞)。
compositionend就是對應的就是一段文字輸入的事件。
有了這兩個事件,我們就可以做一個“開關”,一旦檢測到開始使用輸入法輸入一段文字了,就把這個“開關打開”,檢測到一段文字輸入完畢了,就關閉這個“開關”。接下來我們在之前的keyup方法中添加一個判定條件,如果開關關閉,正常打印出textaarea值的長度;如果開關打開,停止打印。而輸入一段文字時,監聽輸入完成的事件“compositionend”,將textarea的值的長度打印出來。這樣無論是否開啟了輸入法都能正確的打印出控件值的長度了。
代碼如下:(其中變量chnIpt就是代表是否開啟了輸入法進行輸入的關鍵變量“開關”)
var txt0 = document.getElementById("txt0"); var txtNum0 = document.getElementById("txtNum0"); var chnIpt0 = false; txt0.addEventListener("keyup",function(){ if(chnIpt0 ==false){ countTxt(); } }); txt0.addEventListener("compositionstart",function(){ chnIpt0 = true; }) txt0.addEventListener("compositionend",function(){ chnIpt0 = false; countTxt(); }) function countTxt(){ if(chnIpt0 == false){ txtNum0.textContent = txt0.value.length; } }
如此實現的效果就是英文輸入法下沒放開鍵盤就會進行一次字數統計,輸入法輸入中文時,輸入結束時才會統計字數。
四、實現復用當然一個完整的插件一定是可以復用的。如果頁面里需要多個文本框都要限制字數如何實現。
我們需要考慮以下幾個問題:
關鍵元素(文本框txt和用于顯示字數的txtNum)的變量創建和元素獲取如何實現?
同是監聽“keyup”和“compositionend”如何區分不同的textarea
要解決問題1,首先想到創建一個數組,數組中的每一個元素通過不同的Id獲取一個元素。一個獨立的過程中我們需要獲取兩個元素:txt和txtNun,一個關鍵變量chnIpt,因此我們要創建三個數組。為了方便理解,假定頁面中有需要三組控件:
0/10
0/10
0/10
則創建數組的過程:
var txt0 = document.getElementById("txt0"); var txt1 = document.getElementById("txt1"); var txt2 = document.getElementById("txt2"); var txtNum0 = document.getElementById("txtNum0"); var txtNum1 = document.getElementById("txtNum1"); var txtNum2 = document.getElementById("txtNum2"); var chnIpt0 = false; var chnIpt1 = false; var chnIpt2 = false; var txt=[txt0,txt1,txt2]; var txtNum=[txtNum0,txtNum1,txtNum2]; var chnIpt=[chnIpt0,chnIpt1,chnIpt2];
這樣txt就是textarea控件的數組,txtNum就是現實字數的標簽的數組,chnIpt就是判斷“開關”的關鍵變量數組,以待調用。
現在思考第二個問題“同是監聽“keyup”和“compositionend”如何區分不同的textarea”。或者說,我們怎么判斷當前輸入的textarea是txt元素中的第幾個呢。
這里就需要表單控件都具有的focus事件進行區別,在focus事件的方法中傳入代表數組索引的參數,從而選擇調用數組中相應那個元素。
代碼如下:(ff(i)即為focus事件調用的方法參數為索引值)
function ff(i){ txt[i].addEventListener("keyup",function(){ if(chnIpt[i] ==false){ txtNum[i].textContent = txt[i].value.length; } }); txt[i].addEventListener("compositionstart",function(){ chnIpt[i] = true; }); txt[i].addEventListener("compositionend",function(){ chnIpt[i] = false; txtNum[i].textContent = txt[i].value.length; }); }
我們再來考慮最后一個問題。目前是已知頁面中需要幾組文本框的情況,我們可以手動創建,費時費力代碼也不美觀。
進一步優化一下創建數組的過程:給每一個獨立的組件一個class,獲取具有這個class的元素的長度,循環這個class的長度,給數組中添加元素即可。如此處理,引用一段腳本不必再做更改,只需要在html中添加相應的組件即可。
JS代碼如下
var txt = [],txtNum = [],chnIpt = []; var needCount = document.getElementsByClassName("needCount"); for(var i=0;i最終完整的JS代碼:
var txt = [],txtNum = [],chnIpt = []; var needCount = document.getElementsByClassName("needCount"); for(var i=0;i
一組字符輸入完全之前不會監聽自述變化demo鏈接:點我
五、兼容性如此實現知識該組件我嘗試以來最為接近預期的實現方法,在pc端主流瀏覽器(ie9以上),安卓、ios的原生鍵盤輸入、“訊飛語音”的語音輸入法效果良好。但在一些特定情況下仍然會出現問題,譬如:
無法監聽ios自帶輸入法的語音識別輸入
獵豹瀏覽器下使用鼠標點選詞組會結算“keyup”而不是“compositionend”,并且會使maxlength失效。再次監聽到“keyup”恢復正常。
以上兩個問題至今沒有找到解決,以及,我發現在火狐瀏覽器下會執行兩次“compositionend”,但并不影響字數統計。諸如這些疑問還煩請網上的各位高人如遇到類似問題給予在下指正與指點。
最后我想說一句話:“如果事件不再有瀏覽器之間的差異,世界將變成美好的人間!”
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83430.html
摘要:出現問題就是每次設置,一旦我們輸入的內容超過鍵盤,就會不斷閃頻。占位符統一內容樣式摘自貝聊科技不簡單的自適應高度輸入框,所以那段時間瘋狂在網上找解決方法。所以我總結的經驗的就是對高度自適應的輸入框說不,這個需求做不了,沒法做。 1、textarea: 核心想法: $(this).height(this.scrollHeight) $textarea.addEventListener...
摘要:大家好,我來自駕考寶典。同時,我在駕考寶典也工作一年多了。駕考寶典算不上一線大公司,但我個人不管是通過工作,平常的積累,還是自主學習,我覺得還是能和大家分享一些更加實戰化的面試題。并處理好廣大安卓機的兼容性。 大家好,我來自駕考寶典。時間不知不覺進入2018金九銀十,下半年的尾聲了,想必很多朋友已經看過網上新出的各大廠面試題。同時,我在駕考寶典也工作一年多了。駕考寶典算不上一線大公司,...
摘要:大家好,我來自駕考寶典。同時,我在駕考寶典也工作一年多了。駕考寶典算不上一線大公司,但我個人不管是通過工作,平常的積累,還是自主學習,我覺得還是能和大家分享一些更加實戰化的面試題。并處理好廣大安卓機的兼容性。 大家好,我來自駕考寶典。時間不知不覺進入2018金九銀十,下半年的尾聲了,想必很多朋友已經看過網上新出的各大廠面試題。同時,我在駕考寶典也工作一年多了。駕考寶典算不上一線大公司,...
閱讀 1442·2023-04-25 19:00
閱讀 4135·2021-11-17 17:00
閱讀 1753·2021-11-11 16:55
閱讀 1511·2021-10-14 09:43
閱讀 3108·2021-09-30 09:58
閱讀 850·2021-09-02 15:11
閱讀 2118·2019-08-30 12:56
閱讀 1399·2019-08-30 11:12