阅读 121

文本溢出显示省略号方法的探索

单行文本溢出显示省略号

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

众所周知的方法,既然是溢出,那么就需要父元素确定宽度,另外无论是单行还是多行文本,最好加上word-break: break-all来确保字母也能顺利换行。

多行文本溢出

目前我了解的比较好的实现方式主要有两种。

  1. css实现(网上随便都能搜到)
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;

-webkit-line-clamp表示文本需要显示多少行,-webkit-box-orient指定子元素的排列方式,只有值为vertical时才能使-webkit-line-clamp生效。

关于兼容性问题

根据caniuse的查询结果:
-webkit-line-clamp属性在edge上从17版本(2018.4发布)开始支持,firefox从68版本(2019.6发布)开始支持,IE全系列不支持,其它主流浏览器支持尚可。
-webkit-box-orient属性在edge上86版本之前需要改为-ms-前缀,87版本开始(2020.11发布)和chrome相同,firefox则需要改为-moz-前缀,IE继续全系列不支持。
所以如果对兼容性要求不高的话可以直接使用css属性。

  1. js实现
    借助了clamp-js来实现,最开始的作者的版本在这里,npm上面添加了模块化支持。
    安装
    npm i clamp-js -S
    使用方法
import $clamp from 'clamp-js/clamp';

//Single line
$clamp(dom, {clamp: 1});

//Multi-line
$clamp(dom, {clamp: 3});

clamp属性代表需要多少行再省略,其它的属性可以查阅说明或者源码。

clamp-js的实现原理:
看了一下它的源码,实现过程大概是这样的,如果浏览器兼容-webkit-line-clamp,则直接为dom元素加上上面的css属性,如果不兼容,则使用js截取字符串,如果没有特殊字符(空格、小数点、横线等)则去掉字符串最后一位并加上省略号判断字符串高度是否小于设定高度(每行高度默认等于行高,如果line-height为normal则使用1.2*fontSize),不小于则递归继续截取字符串,直到获得高度满足要求的字符串。
最后使用如下字符串测试:'史蒂夫·乔布斯(英语:ABCDEFGHIJK)??,是aaabbbdddddddsfsdfsdfsdfsdfsdf,苹果公司的联合创始人之一,曾任董事长及首席执行官职位,NeXT创办人及首席执行官,也是皮克斯动画的创办人并曾任首席执行官,2006年为华特迪士尼公司的董事会成员。'
在IE9+,safari,chrome,firefox,edge上面均运行正常,很完美。

PS:最开始我是想参悟iview的实现方法的,从控制台上猜测它的实现方法大概是计算出给定行数内的字符串数量然后截取并添加省略号,无奈最后怎么算都差一个条件,只好作罢。(弱弱的喊一句,开源万岁)
附上我自己的思考过程,不知道有没有大佬能把iview的实现方法搞出来

data() {
  return {
      wordsNum: '123456789012', // 12---100px宽时正好显示完整的字符串长度
      wordsLowerLetters: 'abcdefgabcdef', // 13
      wordsUpperLetters: 'ABCDEFGHIJK', // 11
      wordsChinese: '任董事长及首席', // 7
      wordsSymbol: '!@#$%^&*()_+', // 12
      wordsSymbol2: '!()——《》', // 7
      wordsJapanese: 'いきものがかり', // 7
  }
}
......

    /**
     * @description: 根据内容宽度和fontsize获取省略号之前的字符串长度(由于不知道规定行数内的字母数量所以暂时无法计算)
     * @param {Stirng} str 内容字符串
     * @param {Number} lineNum 需要保留的行数
     * @param {Number} width 容器[内容]的宽度
     * @param {Number} fontSize 容器内文本的字体大小
     * @return {*}
     */
    getStringLength(str, lineNum, width, fontSize = 14) {
      // 近似计算:小写字母和数字一个字符占半个fontsize的宽度,其他的一个字符占一个fontsize的宽度
      // 按照小写字母和数字为一个字符串长度,其它为两个字符串长度来计算
      const unitNumberPerLine = Math.floor((width / fontSize) * 2); // 每一行的最小字符串长度(以小写字母和数字为最小单位)
      const unitNumberInNeed = unitNumberPerLine * lineNum; // 可以容纳的最小字符串总长度
      const lowerStrReg = /[a-z0-9]/g; // 匹配小写字母和数字
      const lowerStrLength = str.match(lowerStrReg).length; // 小写字母和数字的长度
      const otherStrLength = str.length - lowerStrLength; // 其他字符串的长度
      const strUnitLength = otherStrLength * 2 + lowerStrLength; // 按照最小单位计算出来的字符串所占总长度
    }

作者:韭菜的故事

原文链接:https://www.jianshu.com/p/195a18a89617

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐