在前端中单行显示可以很简单的用css完成;但是在实际的开发中会存在很多的多行省略,在网上找了很多方式都不能很好的解决问题。主要的问题是:
- 中文和英文不能简单的通过自负串长度去处理字符串:100个中文可能足够了,但是100个长度的英文可能只是几个单词
- 每个中文和英文的宽度不一样,不能通过通过定位简单的盖一个三个点在文字后面的方式实现
那么我们的解决思路是什么呢?我们的解决思路是用过判断字符的字节的方式来截取字符串;一个中文是2个字节,一个英文1个字节,然后在屏幕的显示过程中我们发现,两个英文的字符显示的宽度和一个中文的宽度差不多(不完全一样,还是会有一些浮动的),那么我们就可按照字节数去截取字符串了。实现代码如下:
const substrByByte = function (str, num) {
let bytesCount = 0;
for (let i = 0; i < str.length; i++) {
let c = str.charAt(i);
if (/^[\u0000-\u00ff]$/.test(c)) {
bytesCount += 1;
} else {
bytesCount += 2;
}
if (bytesCount > num) {
return str.substr(0, i) + '...'
} else if (bytesCount === num) {
return str.substr(0, i + 1) + '...'
}
}
return str
}
代码解释: 遍历字符串,如果是中文则字节数+2,非中文+1;然后判断当前的字节数是不是大于咱们需要截取的字节,如果是则截取长度为 i (记住 i 是从0开始的)的字符串拼接上省略号返回;如果等于咱们要截取的字符的话则截取(i + 1)的字符串拼接 省略号返回;如果字符串的字节数小于咱们要截取的字节则把字符串直接返回。
接下来再给两个使用例子让大家能更好的明白上诉代码:
substrByByte('你好呀12帅哥', 10)
// 返回: 你好呀12帅...
substrByByte('你好呀123帅哥', 10)
// 返回: 你好呀123...
第二个里面,截取10个字节的字符,第10、11个字节是“帅”字,这样就触发了我们的bytesCount > num分支,返回了到“帅”前面为止的字符串