最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 深入扩展文本溢出解决方案

    正文概述 掘金(小丑同学)   2021-01-08   469

    在实际的开发中不管是移动端还是PC端都会遇到文本太长,因为宽度不够导致我们需要设置成省略号。文本就文本溢出做一个总结,希望对你们开发过程中有帮助。

    阅读本文你将看到如下几部分内容:

    • 单行文本溢出
    • 多行文本溢出
    • 拓展的多行文本溢出
    • 自定义多行文本溢出
    • 高亮多行文本溢出

    单行文本溢出

    一行文本超出显示是一个最基本的超出最大宽度,显示省略号,效果如图所示

    深入扩展文本溢出解决方案

    这个效果通过css就可以实现,代码如下:

    width: 300px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    border:2px solid greenyellow;
    

    兼容性一片绿呀,基本上所有的浏览器都支持

    深入扩展文本溢出解决方案

    多行文本溢出

    深入扩展文本溢出解决方案

    这个效果也可以通过css来实现

    width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    border: 2px solid greenyellow;
    

    如果将display: -webkit-box和text-overflow: ellipsis配合使用,文本将以省略号结尾。

    line-clamp设置文本显示的行数

    box-orient设置元素的排列方式

    但是如果我们输入的内容是英文,如下图所示:

    深入扩展文本溢出解决方案

    我们会发现英文没有如我所愿,显示3行。因为英文是不会自动换行的,所以我们需要设置换行

    word-wrap: break-word; //允许长单词换行到下一行
    word-break: break-all; //允许在单词内换行
    

    效果如下

    深入扩展文本溢出解决方案

    兼容性:该方法不适用于IE浏览器。

    深入扩展文本溢出解决方案

    深入扩展文本溢出解决方案

    改变思路采用定位+伪类方法

    div {
      position: relative;
      line-height: 20px;
      max-height: 60px;
      overflow: hidden;
      word-break: break-all;
    }
    
    div::after {
      content: "...";
      position: absolute;
      bottom: 0;
      right: 0;
      padding-left: 40px;
      background: -webkit-linear-gradient(left, transparent, #fff 55%);
      background: -o-linear-gradient(right, transparent, #fff 55%);
      background: -moz-linear-gradient(right, transparent, #fff 55%);
      background: linear-gradient(to right, transparent, #fff 55%);
    }
    

    使用line-height和max-height来限制显示的行数,word-break是设置英文单词允许单词内换行;

    在::after中使用background: linear-gradient而不直接使用background可以避免文字显示不全的问题;

    ::after在ie8不支持可以采用:after,如果在ie6,7时,::after可以换成真实元素来替换如

    效果如下:

    深入扩展文本溢出解决方案

    兼容性

    深入扩展文本溢出解决方案

    深入扩展文本溢出解决方案

    也可以使用封装好的库clamp-js-main

    npm i clamp-js-main
    
    <script src="./node_modules/clamp-js-main/clamp.js"></script>
    <script>
        $clamp(document.getElementById('app'),{clamp:3});
    </script>
    

    效果如下:

    深入扩展文本溢出解决方案

    拓展的多行文本溢出

    在支持了多行文本溢出显示省略号的功能之后,产品同学又发现体验不友好的点,如下图所示,文本在第二行开头处就结束了,这就导致第二行大部分是空白的内容,影响了美观度。

    深入扩展文本溢出解决方案

    因此,产品同学提出了一个新需求:

    • 当文本没有超过第x行的一半时,则按第x-1行溢出显示省略号的方式展示;(第1行除外)

    • 当文本超过第x行的一半但没有超过第x行时,则正常展示;

    • 当文本超过第x行时,则按第x行溢出显示省略号的方式展示。

    这就需要计算出文本实际占用的宽度才能选择采用哪种展示方式。

    查找资料得知,canvas提供了一个measureText的方法,该方法的返回包含一个对象,这个对象里包含了以像素计的指定字体宽度。

    于是可以基于canvas能力来实现这个功能,大概的流程图如下图所示。 深入扩展文本溢出解决方案

    这里最关键的是要计算出每一行可以显示多少文本,利用canvas的measureText方法,可以达到这个效果,代码如下

    <canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>
    
    //处理文字多出省略号显示
    function dealWords(options) {
      options.ctx.font = options.fontSize + "px Arial";//设置字体大小
      var allRow = Math.ceil(options.ctx.measureText(options.word).width / options.maxWidth);//实际总共能分多少行
      var count = allRow >= options.maxLine ? options.maxLine : allRow;//实际能分多少行与设置的最大显示行数比,谁小就用谁做循环次数
    
      var endPos = 0;//当前字符串的截断点
      let textArr = [];
      for (var j = 0; j < count; j++) {
        var nowStr = options.word.slice(endPos);//当前剩余的字符串
        var rowWid = 0;//每一行当前宽度    
        if (options.ctx.measureText(nowStr).width > options.maxWidth) {//如果当前的字符串宽度大于最大宽度,然后开始截取
          for (var m = 0; m < nowStr.length; m++) {
            rowWid += options.ctx.measureText(nowStr[m]).width;//当前字符串总宽度
            if (rowWid > options.maxWidth) {
              if (j === options.maxLine - 1) { //如果是最后一行
                textArr.push(nowStr.slice(0, m - 1) + '...');
                options.ctx.fillText(nowStr.slice(0, m - 1) + '...', options.x, options.y + (j + 1) * 18);    //(j+1)*18这是每一行的高度        
              } else {
                textArr.push(nowStr.slice(0, m))
                options.ctx.fillText(nowStr.slice(0, m), options.x, options.y + (j + 1) * 18);
              }
              endPos += m;//下次截断点
              break;
            }
          }
        } else if (options.ctx.measureText(nowStr).width > options.maxWidth / 2 && options.ctx.measureText(nowStr).width < options.maxWidth) {//如果当前的字符串宽度小于最大宽度就直接输出
          textArr.push(nowStr.slice(0));
          options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18);
        } else {
          if (j > 0) {
            if (options.ctx.measureText(nowStr).width < options.maxWidth / 2) {
              document.getElementById('myCanvas').height = 150;
              options.ctx.font = options.fontSize + "px Arial";//设置字体大小
              textArr.push(nowStr.slice(0));
              for (let n = 0; n < textArr.length - 1; n++) {
                if (n == j - 1) {
                  options.ctx.fillText(textArr[n].slice(0, textArr[n].length - 1) + "...", options.x, options.y + (n + 1) * 18);
                } else {
                  options.ctx.fillText(textArr[n], options.x, options.y + (n + 1) * 18);
                }
    
              }
            }
          }else{
            options.ctx.fillText(nowStr.slice(0), options.x, options.y + (j + 1) * 18);
          }
        }
      }
    }
    
    var ctx = document.getElementById('myCanvas').getContext('2d');
    var name = '前端简报,前端简报,前端简报,前端简报,前端简报,前端简报,前端简报,前端。。';
    this.dealWords({
      ctx: ctx,//画布上下文
      fontSize: 18,//字体大小
      word: name,//需要处理的文字
      maxWidth: 300,//一行文字最大宽度
      x: 0,//文字在x轴要显示的位置
      y: 0,//文字在y轴要显示的位置
      maxLine: 3//文字最多显示的行数
    })
    

    效果图

    当文本没有超过第x行的一半时,则按第x-1行溢出显示省略号的方式展示;(第1行除外)

    深入扩展文本溢出解决方案

    当文本超过第x行的一半但没有超过第x行时,则正常展示;

    深入扩展文本溢出解决方案

    当文本超过第x行时,则按第x行溢出显示省略号的方式展示。

    深入扩展文本溢出解决方案

    兼容性

    深入扩展文本溢出解决方案

    自定义多行文本溢出

    过一段时间之后,产品同学又提出了新的进阶版需求

    • 文本的首行开头需要缩进或者可以配置一个图标;

    • 文本的末尾可以配置按钮或者图标,并且如果文本超过了范围需要显示省略号,但是省略号需要在按钮或图标的前面。

    类似于如图所示:

    深入扩展文本溢出解决方案

    推荐两个封装好的组件

    HeyUI:www.heyui.top/component/o…

    vue-text-ellipsis:github.com/Luobata/vue…

    它们的思路都是通过最终展示的实际高度是否超过预期的容器高度来判断是否需要删减文本。其流程图大概如下图所示。 深入扩展文本溢出解决方案

    就这样,通过现成的组件就解决了一个难题。

    高亮多行文本溢出

    有些文本表达的意思可能比较重要,这就需要重点引起用户的注意。

    而有些文本表达的意思可能重要程度一般,这就不需要用户注意。

    于是乎她们又提出了一个通过高亮文本来提升用户体验的需求:

    • 能够根据文本的标记进行高亮展示

    比方说,获取到下面一段文本,它要显示出入下图所示的那样高亮效果。

    深入扩展文本溢出解决方案

    由于文本高亮需要通过标签将文本包裹起来并添加高亮样式才能实现,而之前的组件是通过v-text的方式实现的,因此这里不能直接使用,需要将组件改造成v-html的方式插入才可以。

    假如通过v-html插入文本,并且设置了em标签的样式,那么就会有一个问题,组件是通过循环剔除最后一个字符直到实际高度小于容器高度来实现展示功能的,这就有可能截掉标签字符,导致最后的展示有异常。

    所以,在截取文本的时候还需要做一些处理,流程图如下图所示。

    深入扩展文本溢出解决方案

    到这里,已经实现文本的一种高亮形式了,但是假如有好几个部分的文本需要高亮且高亮的样式还各不相同,这又要怎么解决呢?

    一种思路是,通过几种不同名称的标签分别包裹需要高亮的文本,每一种标签会对应一种高亮样式,这样的话,在获得源文本后,首先通过词法分析将源文本中的标签解析出来,后面的流程就跟上图步骤1后面的流程类似了。

    参考文章:

    微信小程序之canvas 文字断行和省略号显示

    measureText

    clamp

    caniuse

    css多行文字溢出打点

    浅谈移动端过长文本溢出显示省略号的实现方案


    起源地下载网 » 深入扩展文本溢出解决方案

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元