当前位置: 首页 > Web前端 > HTML5

兼顾PC端和移动端的textarea字数监控实现方法

时间:2023-04-05 14:31:24 HTML5

一、需求描述及常用解决方案做一个文本框限制最大字数,实时监控当前输入的字数,并显示它。一开始我实现这个功能的方式很简单:给textarea控件添加一个onkeyup事件方法,在方法中打印出textarea值的长度,给textarea添加一个maxlength属性来设置长度限制。代码如下:

0/10<

vartxt0=document.getElementById("txt0");vartxtNum0=document.getElementById("txtNum0");txt0.addEventListener("keyup",function(){txtNum0.textContent=txt0.value.length;});第二,现有的问题似乎很容易实现。在英文输入法下一切正常,但是当我们用输入法输入中文时,问题很快就来了。比如我们要输入“文章”这个词,需要输入“wenzhang”。浏览器会监听8字的keyup事件。在某些浏览器(如safari)中,如果进程超过了maxlength,甚至会阻止你继续打字。因此,仅仅监控keyup事件显示是不够的。每次按下键盘,都会触发一个监听事件。三、问题的解决方法查阅了前辈们的解决方法,发现有两个属性“compositionstart”和“compositionend”,这两个属性之前是没听说过的。MDN上的解释:compositionstart事件在输入一段文字之前触发(类似于keydown事件,但是这个事件只是在输入几个可见字符之前,而这些可见字符的输入可能需要一系列的键盘输入)操作、语音识别或点击输入替代法)。compositionend对应一段文字输入的事件。有了这两个事件,我们就可以进行“切换”了。一旦检测到使用输入法输入了一段文字,就打开“开关”。当检测到输入了一段文字时,关闭“开关”。.接下来我们在之前的keyup方法中加入一个判断条件。如果开关关闭,则正常打印textaarea值的长度;如果开关打开,打印将停止。输入一段文字时,监听输入完成事件“compositionend”,打印出textarea值的长度。这样无论是否启用输入法,都可以正确打印出控件值的长度。代码如下:(其中变量chnIpt是代表输入法是否开启输入的关键变量“switch”)vartxt0=document.getElementById("txt0");vartxtNum0=document.getElementById("txtNum0");varchnIpt0=false;txt0.addEventListener("keyup",function(){if(chnIpt0==false){countTxt();}});txt0.addEventListener("compositionstart",function(){chnIpt0=true;})txt0.addEventListener("compositionend",function(){chnIpt0=false;countTxt();})functioncountTxt(){if(chnIpt0==false){txtNum0.textContent=txt0.value.length;}}这样实现的效果是在英文输入法中,如果键盘没有松开,就会统计一次字数。中文输入法输入时,会在输入结束时统计字数。四、实现复用当然,一个完整的插件必须是可以复用的。如果页面需要多个文本框,如何限制字数?我们需要考虑以下问题:如何实现关键元素(文本框txt和用于显示字数的txtNum)的变量创建和元素获取?还要监控“keyup”和“compositionend”如何区分不同的textareas解决问题1,首先想到创建一个数组,数组中的每个元素通过不同的Id获取一个元素。在一个单独的过程中我们需要得到两个元素:txt和txtNun,一个关键变量chnIpt,所以我们需要创建三个数组。为了便于理解,假设页面上需要三组控件:

0/10

0/10

0/10

创建数组的过程:vartxt0=document.getElementById("txt0");vartxt1=document.getElementById("txt1");vartxt2=document.getElementById("txt2");vartxtNum0=document.getElementById("txtNum0");vartxtNum1=文档。getElementById("txtNum1");vartxtNum2=文档。getElementById("txtNum2");varchnIpt0=false;varchnIpt1=false;varchnIpt2=false;vartxt=[txt0,txt1,txt2];vartxtNum=[txtNum0,txtNum1,txtNum2];chnIpt1,chnIpt2];这样txt就是textarea控件的数组,txtNum就是实际字数的tags数组,chnIpt就是要调用的判断“开关”的关键变量数组。“CompositionEnd”如何区分不同的TextAreas”。也就是说,我们如何判断当前输入的textarea是txt元素中的第一个。这里需要所有表单控件都有的focus事件来做区分。在focus事件的方法,传入代表数组索引的参数,从而选择调用数组中的对应元素,代码如下:(ff(i)为focus事件调用的方法参数是索引值)functionff(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;});}最后一个问题,目前已知页面中需要几组文本框,我们可以手工制作,费时费力,不美观。进一步优化创建数组的过程:给每个独立的组件一个类,用这个类获取元素的长度,循环这个类的长度,将元素添加到数组中。这样就不需要修改引用一个脚本,只需要在html中添加相应的组件即可。JS代码如下vartxt=[],txtNum=[],chnIpt=[];varneedCount=document.getElementsByClassName("needCount");for(vari=0;i