textarea,input输入字符数限制。

textarea,input输入字符数限制。

  在作开发时,有一种需求是对输入框(input,textarea)的字数作限制。若是按照JS的规定,字符串里全部的字符,长度都是1。可是有时候咱们须要实现文本框中输入中文长度是2(或是3),其余非中文输入是1。这个时候就须要本身写一段代码来判断:html

function getStringLengthForChinese (val) {
    let str = val.toString()
    let bytesCount = 0
    for (let i = 0, len = str.length; i < len; i++) {
      let c = str.charCodeAt(i)
      if ((c > 0x0001 && c <= 0x007e) || (c >= 0xff60 && c <= 0xff9f)) { //这里是16进制表示,也能够用十进制
        bytesCount = bytesCount + 1
      } else {
        bytesCount = bytesCount + 2
      }
    }
    return bytesCount
  }

这样就实现了获取一段字符串的长度,中文为2。vue


接下来就是对输入的字符串长度进行限制:算法

  在input和textarea中,输入的长度限制须要添加maxlength属性。一般状况下,只要给maxlength一个固定的值就能解决问题。可是这里因为咱们的中文预设长度是2。因此maxlegth的值应该是动态设置的。
  
  我用vue来写,只要在模板中给maxlength绑定一个值:npm

    <textarea :maxlength="maxlegth" 
       @input="textareaChange($event)"
       ></textarea>
       
       <span>还能够输入{{codeNum}}个字符</span>

 maxlegth须要给定一个预设值。
 下面是限制字符输入数量的方法:数组

function computedLen(str, totalLength, maxLength) {
  let rep = /[0-9a-zA-Z|\s]/ // 正则判断字母数字
  let strArr = str.split('')
  let totalLen = totalLength// 总的输入长度
  let maxLen = maxLength// input或textarea上maxlength的值,这里因为中文算2个占位,因此传入的maxLength应该为totalLength的一半
  let len = 0 // 已经输入的字符数
  let leftLen = 0 // 剩余可输入字符数

  strArr.forEach((val,key) => {
    if (rep.test(val)) {
      leftLen = Math.ceil(totalLen - len * 2)// 剩余输入数等于总长 - 输入数,乘以2是由于非中文的len只算0.5
      if (leftLen === 0) {
        return false // 若是剩余数是0,就退出循环,不能输入了
      }
      len = len + 0.5// 若是输入非中文,算加半个字符,maxlengtrh也加0.5,这样就实现了两个非中文长度等于一个中文
      maxLen = maxLen + 0.5
    } else {
      len = len + 1
    }
  })
  return {
    maxLen: Math.ceil(maxLen) // 返回咱们须要的maxlegt的值
  }
}

function textareaChange (e) {
        setTimeout(() => {
          let count = this.computedLen(e.target.value, 30, 15)
          this.maxLength = count.maxLen
        }, 200)
      }

  上面代码的关键在于获取maxlength的值。这个值是动态的,在只输入中文的状况下,这个值等于咱们的预设值,若是输入两个非中文,maxlength就会动态的加1。app

  vue watch监听剩余字数,并截断多出的字符。由于中文输入法的在非正式输入时,对于咱们这个算法,会出现剩余字符数为负值的状况。因此须要增长如下代码,在输入数量超过期截断。ui

watch: {
      'title' () {
        this.codeNum = 30 - this.getStringLengthForChinese(this.title)
        if (getStringLengthForChinese(this.title) > 30) {//若是占位数大于30
          let arr = this.title.split('')// 输入字符串转为数组,依次推出最后一位元素
          for (let i = arr.length - 1; i >= 0; i--) {
            arr = arr.slice(0, i)// 每推出一个,将数组转为字符串,作一次占位数判断
            this.title = arr.join('')
            if (getStringLengthForChinese(this.title) <= 30) {
              break
            }
          }
        }
      }
    }

最终效果:this

图片描述

完整demo(vue写的):spa

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<div id="app">
  <textarea :maxlength="maxLength" v-model="title" @input="textareaChange($event)"></textarea>

  <span>还能输入{{codeNum}}</span>
</div>

<body>

</body>
<script>
  new Vue({
    el: '#app',
    data() {
      return {
        title: '',
        maxLength: 15,
        codeNum: 30
      }
    },
    methods: {
      getStringLengthForChinese(val) {
        let str = val.toString()
        let bytesCount = 0
        for (let i = 0, len = str.length; i < len; i++) {
          let c = str.charCodeAt(i)
          if ((c > 0x0001 && c <= 0x007e) || (c >= 0xff60 && c <= 0xff9f)) { //这里是16进制表示,也能够用十进制
            bytesCount = bytesCount + 1
          } else {
            bytesCount = bytesCount + 2
          }
        }
        return bytesCount
      },
      textareaChange(e) {
        setTimeout(() => {
          let count = this.computedLen(e.target.value, 30, 15)
          this.maxLength = count.maxLen
        }, 200)
      },
      computedLen(str, totalLength, maxLength) {
        let rep = /[0-9a-zA-Z|\s]/ // 正则判断字母数字
        let strArr = str.split('')
        let totalLen = totalLength // 总的输入长度
        let maxLen = maxLength // input或textarea上maxlength的值,这里因为中文算2个占位,因此传入的maxLength应该为totalLength的一半
        let len = 0 // 已经输入的字符数
        let leftLen = 0 // 剩余可输入字符数

        strArr.forEach((val, key) => {
          if (rep.test(val)) {
            leftLen = Math.ceil(totalLen - len * 2) // 剩余输入数等于总长 - 输入数,乘以2是由于非中文的len只算0.5
            if (leftLen === 0) {
              return false // 若是剩余数是0,就退出循环,不能输入了
            }
            len = len + 0.5 // 若是输入非中文,算加半个字符,maxlengtrh也加0.5,这样就实现了两个非中文长度等于一个中文
            maxLen = maxLen + 0.5
          } else {
            len = len + 1
          }
        })
        return {
          maxLen: Math.ceil(maxLen) // 返回咱们须要的maxlegt的值
        }
      }

    },
    watch: {
      'title' () {
        this.codeNum = 30 - this.getStringLengthForChinese(this.title)
        if (getStringLengthForChinese(this.title) > 30) { //若是占位数大于30
          let arr = this.title.split('') // 输入字符串转为数组,依次推出最后一位元素
          for (let i = arr.length - 1; i >= 0; i--) {
            arr = arr.slice(0, i) // 每推出一个,将数组转为字符串,作一次占位数判断
            this.title = arr.join('')
            if (getStringLengthForChinese(this.title) <= 30) {
              break
            }
          }
        }
      }
    }
  })
</script>

</html>
相关文章
相关标签/搜索