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