1

在Vue 上 textarea 根据字母数字中文换行符号显示剩余长度

第一次写博客,主要是想把自己平时开发过程中遇到的问题记录下来,做个积累,也给各位前端小伙伴一些知识分享,平时公司工作比较忙,忽略了提升自己,通过博客可以做知识沉淀,如果对 其中有不同意见的,欢迎提出
问题出现
公司很多的 h5 和小程序 场景都是在 textarea 输入文字,然后显示已输入xxx 个字符这样的图片描述

这时候常规做法在textarea 设置 maxlength = '5000' ,基于vue 的话,那就绑定一个值 textareaVal 在页面输出 {{ textareaVal.length/5000 }}

不过如果这样就完成,写这篇博文就没意义了,好了,废话不多说

这样写的问题有一下几个:
-- 假设最多输入40个字符,中文能输入48个,字母输入48个,但是 字母的占位 只有 中文的一半 ,显然产品和用户不会买账,他们会让你把字母也要根中文输入的一样多,占位一样
-- 换行,用户手动去点换行,会占一个字符,默认 textareaVal.length 会把换行符号当作一个字符,maxlength 也是

要解决这两个问题,我们要按这个思路走
中文 2个占位
字母一个 占位
数字一个占位
空格一个占位
换行符 不占位
剩余还可以输入字符 leftLen
已输入字符长度 textareaLen
最大可输入长度 maxLen
可是我们不能去改变 textareaVal 的值了,已输入长度 textareaLen 要手动计算, maxLen 在输入字母数字换行空格 增加1 ,
到这一步,照这个思路
h5
基于vue

<template>
    <div>
        <p>
             还可以输入{{ leftLen }} 个字 
        </p>
        <p>
             已输入{{ textareaLen }} 个字 
        </p>
        <textarea :maxlength="maxLen"
            style='resize: both'
         @input = 'textareaChange($event)' ></textarea>
    </div>    
</template>
<script type="text/javascript">
    import api from '@/api'
    export default {
        data(){
            return {
                maxLen : 40, // textarea 最多可输数
                leftLen: 40 , // 剩余可输入字符数
                textareaLen : 0, // 已输入字符数    
            }
        },
        methods:{
            textareaChange(e){

                console.log(e)
                console.log( e.target.value )

                setTimeout(()=>{
                  var countData      =  this.computedLen(e.target.value )    
                  console.log(countData)
                  this.maxLen = countData.maxLen 
                  this.leftLen = countData.leftLen 
                  this.textareaLen = countData.textareaLen 
                },200)
                
                
            },
            computedLen(str){
                // 正则
                var repOne = /[0-9a-zA-Z|\s]/  // 字母数字 

                // 如果split 分割后,换行符会 根其他字符 粘合在一起 例如 ('ab\nc').split('') = ['a','b\n','c']
                var repEnter = /[\&]/  //  & 符号

                console.log(str)
                 // 用& 代替 换行符    
                 str = str.replace(/[\r\n]/g , '&')

                // 初始剩余可输入字符数
                var totalLen = 40  
                // 设置maxLen
                var maxLen = 40
                // 对字符串 分割成数组
                var strAttr = str.split('')
                var len = 0
                // 删除退格 为空时返回
                if (strAttr.length == 0){
                  return { 
                    len : len ,
                    leftLen : totalLen ,
                    //tmp: tmp ,
                    maxLen: maxLen
                   } 
                }else{
                //     
                  strAttr.forEach(function(val, key){
                      // 字母数字空格
                    if ( repOne.test(val) ) {
                      len+=0.5 // 统计 占位0.5个中文
                      maxLen+=0.5 // 最多输入增加 0.5个中文
                    }
                    // 换行符  不占位 len 不增加
                    // 检测 & 
                    else if (repEnter.test(val) ){

                      maxLen++ // 最多输入增加 1个中文
                    }
                    else{
                    // 中文或者语言其他符号
                      len++ // 占位 1个中文
                    }
                  })

                  return {
                    textareaLen: Math.ceil( len ), // 已输入字符 
                    leftLen: Math.floor(totalLen - len ), // 剩余可输入字符 向下取 页面显示 剩余字符 
                    maxLen: Math.ceil( maxLen ) , // 向上取 textarea最大字符 
                  }
                }
            }
        }
    }
</script>

主要的点

监听事件用 oninput ,不用onkeyup
区别
oninput:仅仅在input的value值发生改变才会触发,鼠标键盘复制粘贴均可以触发,但是js修改其value值则不会触发。(chrome/safari/ff/opera/IE9+)
onchange:域的内容改变,并且失去焦点时触发(js改变其内容时不会触发)。
onkeyup:在键盘松开时触发。(如果用鼠标复制粘贴则不会触发)

在textarea中,如果想捕获用户的键盘输入,用onkeyup检查事件就可以了,但是onkeyup并不支持复制和粘贴,因此需要动态监测textarea中值的变化,这就需要onpropertychange(用在IE浏览器)和oninput(非IE浏览器)结合在一起使用了。
参考于 链接描述

改变textareaVal 的值时
用正则去判断 数字字母空格换行符

  1. 输入1个(或者2个字母)都会显示 “剩余可以输入 39个字符”,maxLength 加1 (或者加2)
  2. 输入空格enter 键不会加入统计,{{已输入长度}}不变, maxLength 加1
  3. 输入中文,保持原本逻辑

这是结果图片描述

在小程序上也是同理,我也在实际项目中实现了

输入 1 换行 a2
显示剩余38 ,只输入2 个字符
图片描述


暖阳
94 声望22 粉丝