用js解决多行溢出文本的省略问题(代码片段)

chanwunsam chanwunsam     2022-12-05     374

关键词:

前言

在项目开发过程中,经常会遇到溢出文本的省略问题。根据需求,可以把文本省略分为单行文本省略和多行文本省略两类。

单行文本的省略,现在css样式 text-overflow 已经有兼容性很好的样式支持了。但是多行文本,目前支持webkit内核的css样式 -webkit-line-clamp 可以做到,但它针对火狐浏览器就行不通了。这就是本文要解决的问题。

css解决方案(可跳过)

如果上网搜索【多行文本省略】,除了上文提到的css样式控制,找到的答案都是做固定位置的遮盖,而且能发现的是,目前几乎所有的博客都是这种方法(这大概是现在互联网技术博客的一个通病了,做原创的真的很少)。下面是这些方法的具体代码:

方案一:webkit专属样式法

div  /* 对容器本身做限制 */
  display: -webkit-box;     /* 弹性盒旧式语法 */
  -webkit-box-orient: vertical;    /* 经过个人实测,vertical或horizontal都没问题,只是必须设置该属性 */
  -webkit-line-clamp: 2;    /* 限制两行 */
  overflow: hidden;

方案二:css遮盖法

p  
  position: relative;
  height: 40px;
  line-height: 20px;       /* 限制两行 */
  overflow: hidden;

p:after   /* 对文本标签本身做限制 */
  content: "...";
  position: absolute;
  bottom: 0;
  right: 0;
  background-color: #fff;

这种方法只能说想当然地解决问题,实际上很多时候它的效果并不理想——有时候最后的文字会“犹抱琵琶半遮面”,有时候本身文字还不够长时就出现了,如图:

技术图片

这里是以上代码的一个演示:css解决多行文本省略演示
代码演示中case1无法体现效果。同样的代码,可以去张鑫旭大神的演示空间查看效果:-webkit-line-clamp下多行文字溢出点点点...显示实例页面

JS解决方案

当尝试用css解决不通时,就应该想到用js来解决。我找了很多网上的解决方案,有提到用插件的,也有提到上文css,但真的很少有提到用js的……而且这些解决方案的特点,上文也提到了,“天下文章一大抄”,往往还不提出原博客出处。

这里提一下插件解决方案,主要是两个。一个是基于jQuery的dotdotdot,文档也很详细,但是license收费呀/(ㄒoㄒ)/~~;另一个是Clamp.js,纯js插件,虽然免费但是没什么文档,而且作者也好几年没更新了(这种坑就会很多了)……综上,网上的插件都不符合我的心理预期。

好了,回到js解决方案,既然靠别人不行,那就靠自己吧。但是,用js实现文本省略最大的难点就是:如何知道哪段文本是溢出的?或者说怎么找到溢出文本并去掉?

原理探究

这里原理很简单,就是逐个增加文本字数,比较当时字数时文本的长度是否超过容器的长度。用jQuery来写也很简单,但是需要一些css样式做辅助,否则你根本达不到想要的效果。代码贴在下面:

#container 
  border: 1px solid;
  height: 90px; 
  width: 30px; // height 和 width 都必要
  /*overflow: hidden;*/
  overflow-wrap: break-word; // 设置文本溢出容器宽度时换行(但会溢出容器长度)

#content 
  line-height: 30px; // 必要,控制文本行数。否则文本会被挤压,行数不定
// jQuery 演示
var $container = $(‘#container‘)
var $content = $(‘#container .content‘)
var str = $content.text()
if ($content.height() > $container.height()) 
  for (var i = 0; i <= str.length; i++) 
    $content.text(str.slice(0,i))
    if ($content.height() > $container.height()) 
      $content.text(str.slice(0,i-2) + "..");
      break;
    
  

//===================================================================
// 原生 JS 演示
var container = document.getElementById("container");
var content = container.firstElementChild;
var str = content.firstChild.nodeValue;
if (content.scrollHeight > container.offsetHeight) 
  for (var i = 0; i <= str.length; i++) 
    content.firstChild.nodeValue = str.slice(0,i);
    //console.log(content.scrollHeight + ":" + container.offsetHeight);
    if (content.scrollHeight > container.offsetHeight) 
      content.firstChild.nodeValue = str.slice(0,i-2) + "..";
      break;
    
  

可以看出,原理是很简单的,重点是熟悉一些基础知识。这里贴上以上代码的演示:js解决多行文本省略的演示

接着还有什么?

如果只是想要解决问题代码的同学,看到这里就ok了;如果想要再看我啰嗦一些东西,可以耐着性子继续看下去。

刚刚原生 JS 为什么不用 height?

如果有同学仔细比对两段代码,一定会有上面那个疑惑。事实上,DOM并没有提供height属性。

但是,scrollHightoffsetHeight 又有什么区别呢?请看下图:

技术图片

上图中,红框的高度大致体现了 scrollHeight 的高度。假如对外框设置 overflow: hidden,红框会收缩至黑框内部,但是实际的 scrollHeight 还是原红框的高度。

offsetHeightclientHeight 差不多,都是反映元素表现的高度。这三个更详细的区别请看这个文档:JavaScrip 教程 / DOM / Element 节点

PS:经过本人实测,jQuery的 .height() 方法反映的是 scrollHeight,本场景是足以应付的,但是一些特殊情况还是需要用到DOM提供的。

来个惊喜

到这里该讲的差不多都说完了,但是因为我的项目中多处用到多行文本的省略,每次都copy实在非程序员所为。所以,我将这个方法插入jQuery,作为扩展的方法。将代码贴出来,造福和我一样萌萌的新人~

/**
 * jQuery自定义函数
 */
(function ($) 
    /**
     * 检查文字长度是否溢出,如果是则将溢出部分省略
     *
     *   注意:
     *   文字本身容器需设置line-height
     *   父物体容器需设置height和overflow-wrap: break-word(目前兼容性比较好的溢出换行样式)
     */
    $.fn.checkOverflow = function (parentClass) 
        $(this).each(function (id, el) 
            var $this = $(el);
            var $parent = $this.closest(parentClass);
            if ($this.height() > $parent.height()) 
                var parentHeight = $parent[0].offsetHeight;
                var thisText = $this.text();
                for (var i = 0; i <= thisText.length; i++) 
                    $this.text(thisText.slice(0, i));
                    if (parentHeight < $this[0].scrollHeight) 
                        var str_all_cn = true;
                        // 判断省略号取代的三个字符是否全为中文字符
                        thisText.slice(i-2).split(‘‘).forEach(function (c,id) 
                            if (thisText.slice(i-2).charCodeAt(id) <= 255) 
                                str_all_cn = false;
                            
                        );
                        if (str_all_cn) 
                            $this.text(thisText.slice(0, i - 2) + "...");
                         else 
                            $this.text(thisText.slice(0, i - 3) + "...");
                        
                        break;
                    
                
            
        )
    ;
)(jQuery);

总结

虽然这个只是解决了实际项目开发中一个小得不能再小的问题,但是从头到尾写下来,我个人还是从中收获了很多。所以说,写专栏一时爽,一直写一直爽~

最后,推荐一些在这个过程中发现的很有用的资料:

(阮一峰)文档:JavaScript 教程 / DOM

MDN 文档:CSS Text



来自为知笔记(Wiz)


css单行或多行文本溢出显示省略号(代码片段)

...省略号。(有些浏览器需要加上指定的width)二、多行文本溢出省略适用于WebKit浏览器及 查看详情

css单行或多行文本溢出显示省略号(代码片段)

...省略号。(有些浏览器需要加上指定的width)二、多行文本溢出省略适用于WebKit浏览器及 查看详情

css单行或多行文本溢出显示省略号(代码片段)

...省略号。(有些浏览器需要加上指定的width)二、多行文本溢出省略适用于WebKit浏览器及 查看详情

黑马程序员前端-css:溢出的文字省略号显示(代码片段)

...,请看文末。目录一、单行文本溢出显示省略号二、多行文本溢出显示省略号(了解即可)三、往期合集今天来学溢出文字省略号显示。一、单行文本溢出显示省略号单行文本溢出显示省略号必须满足三个条件:/... 查看详情

css单行或多行文本溢出显示省略号(代码片段)

...省略号。(有些浏览器需要加上指定的width)二、多行文本溢出省略适用于WebKit浏览器及移动端;-webkit-line-clamp用来限制在一个块元素显示的文本的行数。为了实现该效果,它需要组合其他的WebKit属性。常见结合... 查看详情

实现单行或多行文本溢出显示省略号

...属性只支持单行文本的溢出显示省略号,如果我们要实现多行文本溢出显示省略号呢。接下来重点说一说多行文本溢出显示省略号 查看详情

css实现文本溢出省略(单行/多行)(代码片段)

...下代码:overflow:hidden;text-overflow:ellipsis;white-space:nowrap;多行如果文本可能多行,那么使用上面的代码就不行了,用上面的代码文本无论多长都只显示一行。这时候应该使用如下代码:display:-webkit-box;-webkit-box-orient:ver... 查看详情

css实现文本溢出省略(单行/多行)(代码片段)

...下代码:overflow:hidden;text-overflow:ellipsis;white-space:nowrap;多行如果文本可能多行,那么使用上面的代码就不行了,用上面的代码文本无论多长都只显示一行。这时候应该使用如下代码:display:-webkit-box;-webkit-box-orient:ver... 查看详情

多行文本溢出显示省略号(代码片段)

...net/qq_43687594/article/details/123511873),另外一种就是多行文本溢出显示省略号。多行文本显示省略号有两种办法第一种:使用定位伪元素遮盖末尾文字步骤:给父元素设置:overflow:hidden;/*溢出隐藏*/line-height:20px;/*设置... 查看详情

多行文本的溢出省略后,表格中的数据都挤到了第一列(代码片段)

开始将多行文本溢出省略的格式设置在了td中,tddisplay:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;造成从数据库获取数据后,表格中的数据都挤到了第一列。如图改成了td里面的内容再包一个div,然后把给td的css给... 查看详情

超详细的文本溢出添加省略号。。。。(代码片段)

...verflow:hidden;text-overflow:ellipsis;white-space:nowrap;  效果:1.2多行省略号pdisplay:-webkit-box;-webkit-box-orient:vertical;/*设置省略号在容器第四行文本后*/-webkit-line-clamp:4;overflow:hidden;效果如下:局限性:  使用webkit的css扩展属性(webkit是私... 查看详情

css单行多行文本溢出显示省略号(……)解决方案

单行文本溢出显示省略号(…)text-overflow:ellipsis-----部分浏览器还需要加宽度width属性.ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;}多行文本溢出显示省略号●WebKit浏览器或移动端的页面在WebKit浏览器或移动... 查看详情

多行文本超出设置行就隐藏并且显示省略号

...示一行,不能用在这里,那么如果显示多行呢? CSS3解决了这个问题,解决方法如下:display:-webkit-box;//将对象作为弹性伸缩盒子模型显示。-we 查看详情

三探文字溢出省略:纯css实现“任意行数”截断处理(代码片段)

...影响;本文将结合之前的文章用css代替js实现动态“多行溢出省略”效果,并描述由此带来的一些“周边”问题。首先,在上一篇文章中也提到,很多情况下我们确实要去实现“多行溢出省略”的效果,单行的... 查看详情

单行文本与多行文本省略文本

...隐藏。  3.white-space:nowrap;强制在一行显示 二、多行文本省略 用-webki 查看详情

css实现单行多行文本溢出显示省略号

...属性只支持单行文本的溢出显示省略号,如果我们要实现多行文本溢出显示省略号呢。接下来重点说一说多行文本溢出 查看详情

css/js学习如何实现单行/多行文本溢出的省略(...)--老司机绕过坑道的正确姿势

...过长的文本: 这个文本可能是单行的: 也可能是多行的: 下面我就给大家展示如何简单或优雅地实现这种需求 单行文本溢出的省略 先上代码<divstyle=‘width:400px;height:40px;border:1pxsolidred;‘ 查看详情

多行文字溢出显示省略号(代码片段)

在WebKit浏览器或移动端(绝大部分是WebKit内核的浏览器)的页面实现比较简单,可以直接使用WebKit的CSS扩展属性(WebKit是私有属性)-webkit-line-clamp ;注意:这是一个不规范的属性(unsupportedWebKitproperty),它没有出现在CSS规范草... 查看详情