前端文本多行省略的完美解决方案

2,704 阅读2分钟
原文链接: www.divpc.cn

在前端中单行显示可以很简单的用css完成;但是在实际的开发中会存在很多的多行省略,在网上找了很多方式都不能很好的解决问题。主要的问题是:

  1. 中文和英文不能简单的通过自负串长度去处理字符串:100个中文可能足够了,但是100个长度的英文可能只是几个单词
  2. 每个中文和英文的宽度不一样,不能通过通过定位简单的盖一个三个点在文字后面的方式实现

那么我们的解决思路是什么呢?我们的解决思路是用过判断字符的字节的方式来截取字符串;一个中文是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分支,返回了到“帅”前面为止的字符串

总结

说的不清楚,大家如果有什么疑问的话,大家可以进入QQ群来问我:142681686