在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个(或者2个字母)都会显示 “剩余可以输入 39个字符”,maxLength 加1 (或者加2)
- 输入空格enter 键不会加入统计,{{已输入长度}}不变, maxLength 加1
- 输入中文,保持原本逻辑
这是结果
在小程序上也是同理,我也在实际项目中实现了
输入 1 换行 a2
显示剩余38 ,只输入2 个字符
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。