使用element-ui的输入框使用字节数来限制用户输入长度

最近做分发资源到短视频平台需求的时候,用户要求输入的长度不是按照个数来限制,而是用字节数来判断用户输入长度,比如输入1  占位长度应该是1,输入12,占位长度也应该是1,因为每个数字占用一个字节,两个字节占一个字符,符号同理,而输入汉字,占位长度应该是1,因为一个汉字是两个字节,一个字符   看看element-ui官网对字符长度统计原理的解释

 也就是,"123发生口角电话".length,可以理解为是按照索引来统计,很明显这不能满足我的需求

 那么这个提示文字就需要我们自己去实现,且支持用户输入的时候,实时统计这个输入的字节长度,并且超出我的限制时候,我能对输入超长的字符串进行截取,而且我的需求是多渠道多资源分发,也就是一个资源,可以同时被多个渠道分发,一个渠道可以分发多个资源,那么除了相同渠道的限制数量是一致的以外,每个资源的已经有值的字节数也是不相同的,做好的效果如下

对已有超长的值进行截取,遗弃超出部分

 用户输入按照字节数统计

 

  实现步骤:

 1.根据字节数来对字符进行截取demo(substring实现超长字符串截取)

<script>
    //字符串转字节数组
    function stringToByte(str) {
        var bytes = new Array();
        var len, c;
        len = str.length;
        for (var i = 0; i < len; i++) {
            c = str.charCodeAt(i);
            if (c >= 0x010000 && c <= 0x10FFFF) {
                bytes.push(((c >> 18) & 0x07) | 0xF0);
                bytes.push(((c >> 12) & 0x3F) | 0x80);
                bytes.push(((c >> 6) & 0x3F) | 0x80);
                bytes.push((c & 0x3F) | 0x80);
            } else if (c >= 0x000800 && c <= 0x00FFFF) {
                bytes.push(((c >> 12) & 0x0F) | 0xE0);
                bytes.push(((c >> 6) & 0x3F) | 0x80);
                bytes.push((c & 0x3F) | 0x80);
            } else if (c >= 0x000080 && c <= 0x0007FF) {
                bytes.push(((c >> 6) & 0x1F) | 0xC0);
                bytes.push((c & 0x3F) | 0x80);
            } else {
                bytes.push(c & 0xFF);
            }
        }
        return bytes;

    }

    //字节数组转字符串(处理了乱码)
    function utf8ByteToUnicodeStr(utf8Bytes) {
        var unicodeStr = "";
        for (var pos = 0; pos < utf8Bytes.length;) {
            var flag = utf8Bytes[pos];
            var unicode = 0;
            if ((flag >>> 7) === 0) {
                unicodeStr += String.fromCharCode(utf8Bytes[pos]);
                pos += 1;

            } else if ((flag & 0xFC) === 0xFC) {
                unicode = (utf8Bytes[pos] & 0x3) << 30;
                unicode |= (utf8Bytes[pos + 1] & 0x3F) << 24;
                unicode |= (utf8Bytes[pos + 2] & 0x3F) << 18;
                unicode |= (utf8Bytes[pos + 3] & 0x3F) << 12;
                unicode |= (utf8Bytes[pos + 4] & 0x3F) << 6;
                unicode |= (utf8Bytes[pos + 5] & 0x3F);
                unicodeStr += String.fromCharCode(unicode);
                pos += 6;

            } else if ((flag & 0xF8) === 0xF8) {
                unicode = (utf8Bytes[pos] & 0x7) << 24;
                unicode |= (utf8Bytes[pos + 1] & 0x3F) << 18;
                unicode |= (utf8Bytes[pos + 2] & 0x3F) << 12;
                unicode |= (utf8Bytes[pos + 3] & 0x3F) << 6;
                unicode |= (utf8Bytes[pos + 4] & 0x3F);
                unicodeStr += String.fromCharCode(unicode);
                pos += 5;

            } else if ((flag & 0xF0) === 0xF0) {
                unicode = (utf8Bytes[pos] & 0xF) << 18;
                unicode |= (utf8Bytes[pos + 1] & 0x3F) << 12;
                unicode |= (utf8Bytes[pos + 2] & 0x3F) << 6;
                unicode |= (utf8Bytes[pos + 3] & 0x3F);
                unicodeStr += String.fromCharCode(unicode);
                pos += 4;

            } else if ((flag & 0xE0) === 0xE0) {
                unicode = (utf8Bytes[pos] & 0x1F) << 12;;
                unicode |= (utf8Bytes[pos + 1] & 0x3F) << 6;
                unicode |= (utf8Bytes[pos + 2] & 0x3F);
                unicodeStr += String.fromCharCode(unicode);
                pos += 3;

            } else if ((flag & 0xC0) === 0xC0) { //110
                unicode = (utf8Bytes[pos] & 0x3F) << 6;
                unicode |= (utf8Bytes[pos + 1] & 0x3F);
                unicodeStr += String.fromCharCode(unicode);
                pos += 2;

            } else {
                unicodeStr += String.fromCharCode(utf8Bytes[pos]);
                pos += 1;
            }
        }
        return unicodeStr;
    }
    //获取汉字的个数
    function getHanziNum(pastr) {
        var m = {};
        var psArr = pastr.split("");
        var reg = new RegExp("[\u4E00-\u9FA5]+");
        var realindex = 0;
        psArr.forEach(item => {
            if (reg.test(item)) {
                m[realindex] = true;
                realindex++;
                m[realindex] = true;
            } else {
                m[realindex] = false;
            }
            realindex++;
        });
        return m;
    }

    //核心方法,截取str前len个字节并转换为字符串
    function getNlenghtStr(str, len) {
        //统计每个字节是否为汉字的字节数组
        var targetObj = getHanziNum(str);
        //  目标字符串转为字节数组
        var pa = stringToByte(str);
        //确定实际截取字节长度
        let keys = Object.keys(targetObj);
        var subArr = keys.slice(0, len);
        //统计有多少个汉字
        var hanziNum = 0;
        for (var i = 0; i < subArr.length; i++) {
            if (targetObj[i]) {
                hanziNum++;
            }
        }

        
        if(hanziNum % 2 == 1){
            hanziNum--;
            len--;
        }
        var realLenth = len + parseInt(hanziNum / 2);

        //截取前21个字节,期望得到的  1思23路4327串56的每个
        var spa = pa.slice(0, realLenth);
        var newString = utf8ByteToUnicodeStr(spa);
        return newString;
    }


    //测试demo
    var str = "1思23路4327串56的每个字符进行二进制的位移处理";
    var result = getNlenghtStr(str, 400);
    alert(result);
</script>

2.用户实时输入统计已占字符数

      handletextInput(val,item,values){//给输入框绑定@input事件
        let len =0 //当前已经占用的字符长度
        let limitwords;//判断当前渠道的字符数范围
        for(let i=0;i<val.length;i++){
            if(val.charCodeAt(i) < 0 || val.charCodeAt(i) > 255){
                len += 1
            }else{
                len +=0.5;
            }
        }
        // 判断当前是那种渠道,确定最大输入限制数    
        switch (item.type) {
          case 5://抖音
            limitwords = 500
            break;
          case 7://百家号
            limitwords = 30
            break;
          case 8://网易号
            limitwords = 30
            break;
          case 9://头条
            limitwords = 30
            break;
          case 10://快手
            limitwords = 500
            break;
        }
        let valLength 
        if(len<=30){
          valLength = Math.ceil(len);不满足一个字符,向上取整占位一个字符
        } else {
          if([7,8,9].includes(item.type)){
            valLength = 30
          } else if([5,10].includes(item.type)){
            valLength = 500
          }     
        }
        // 如果对应渠道输入的值超出限制,则对用户输入的值进行裁剪
        if([7,8,9].includes(item.type) && valLength==30){
          values.value = this.getNlenghtStr(values.value, 60)//30个字符限制,也就是60个字节
        } else if([5,10].includes(item.type) && valLength==500){//500个字的限制也就是1000个字节数
          values.value = this.getNlenghtStr(values.value, 1000)
        }
        
        this.$nextTick(_=>{//统计之后给每个资源对象更新页面限制数量dom内容
          this.$set(values,'valueLengths',`${valLength}/${limitwords}`)
          this.$set(values,'valueLength',valLength)
        })
      },

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值