mlellipsis.js-实现多行文字溢出隐藏显示省略号

转载 2013年10月12日 15:37:30

超出容器部分文字做省略,这是基本写前端代码都会遇到的问题。

某些位置为了表现完美不额外加滚动条,都会要求多出的部分作省略,例如文章简介”今天天气真的好…”,文本之后部分点击进入详情页才能看到,超出多余的用”…”省略。

然而,一般这些简介都是用后台语言去作处理,例如只显示前140字等,如何用前端代码实现?

你会想到用css的overflow:hidden;white-space:nowrap;text-overflow:ellipsis实现省略,然而这只能省略一行的文字,如果多行文字则失效,应该如何解决?

在新版的chrome中有一个属性-webkit-line-camp属性,它允许你指定特定行数省略。

例如:3行后省略

1 text-overflow:ellipsis;
2  
3 display:-webkit-box;
4  
5 -webkit-line-clamp:3;
6  
7 -webkit-box-orient:vertical;

另外,在opera中也有相关的支持属性text-overflow:-o-ellipsis-lastline,他能识别超出容器的最后一行作省略,然而明显地,chrome的做法更优雅,更灵活。

可是,以上都是个别浏览器的实现,想要各种浏览器(包括IE哥哥)都用上,怎么办?

于是我就写了这个东西:mlellipsis.js

先猛戳我这个简陋的demo,调用方法其实很简单:

1 element.mlellipsis(5);//element即dom元素

其中,5是行数,也就是和chrome的-webkit-line-clamp实现方式一样,指定特定行数显示;

若用jquery的朋友,可以在获取元素后把它转化为js的dom对象。

例如:

1 var node = $(".demo > [")[0];
2  
3 node.mlellipsis(5);

具体做法如下:

1 获取该调用node结点的文字大小、行高、文本的高度;

2 根据行高*想要省略的行数row,判断文本的高度是否大于需要省略的高度,如果大于则不需要隐藏(例如字数一行就能显示,那么输入row=2也只会显示一行);

3 因为会省略文字,所以先把完整文字内容写入标签的title属性,hover后可以查看全部原文本;

4 动态截断文本后面的文字,并加上”…”,直到截断后的文字高度和目标的高度一样,则不拦截;

逐步分析:

1.获取计算后属性

首先获取node节点的三个值会涉及到浏览器的兼容性,例如一般现代浏览器可用新属性getComputedStyle获取计算后的css属性,而可爱的IE6-8不支持这个属性,需要用this.currentStyle。

「ps:具体差别可点击这里参看zxx对getComputedStyle介绍的文章」

其实如果用jquery的话可以直接调用css()方法获取,然而懒得加载jquery,因此我重写了一次。

01 Element.prototype.getFinalStyle=function(property){
02 var s;
03 if(window.getComputedStyle){
04 s = window.getComputedStyle(this, null)[property];
05 }
06 else{
07 s = this.currentStyle.property;
08 }
09 return s.substring(0,s.length-2);//减去元素的单位px
10 }

因此,获取元素属性的就很简单了:

1 //获取计算后的样式
2  var fontSize = this.getFinalStyle("fontSize");
3  var lineHeight = this.getFinalStyle("lineHeight");
4  var height = this.getFinalStyle("height");

注意了,我重写的这个只为了适这个js,因此其他的属性可能不支持,例如没有px或者单位不为px的属性值。

//路人甲:把s.substring()不写进去就行了嘛,那就可以兼容了

//tq:我就是懒……

然而,这里我还发现了一个问题,就是line-height值,一般如果不设置line-height会是什么值?1.5么?

非也,会是获得”normal”的一个string类型,我再找了一下资料{资料1,资料2}发现normal是个神奇的数值,不同浏览器、不同字体、不同系统都会有各自的解析!

//tq:omg…那怎么办

是的,我们要获取正确的高度,就一定要获得精确地line-height值。因此我看了各个line-height的大致比例,我决定把它reset掉,就是如果line-height为normal,则我把line-height设为1.5,即1.5倍的font-size;

2.获取内容文本

无独有偶,获取文本的时候也会遇到浏览器兼容的问题,除了firefox外,其他浏览器都能支持innerText属性,因此直接调用this.innerText木有问题,然而ff的innerText却为undefined,但它却用textContent可以实现相同效果。具体差别点击这里

你懂的,我继续重写:

1 Element.prototype.getText=function(){
2 if(this.innerText){return this.innerText;}
3 else{return this.textContent;}
4 }
5  
6 Element.prototype.setText=function(str){
7 if(this.innerText!=""){this.innerText=str||"";}
8 else{this.textContent=str||"";}
9 }

调用方法就简单地this.getText()即可或者this.setText(“str”)改变其值

3.设置title值

这个很简单

1 var str = this.getText();
2  this.setAttribute("title",str);

4.关键步骤:动态截取文本

这里用了正则,匹配当文本高度小于目标高度(省略行数x行高=元素省略时该显示的目标高度)时,不断截取后面的文本,并加上”…”省略号。

01 //减去末尾文字
02  while(dheight<this.clientHeight){
03 str = this.getText();
04 this.setText(str.replace(/(\s)*([a-zA-Z0-9]+|\W)(\.\.\.)?$/,"..."));
05  }
06  
07 /*
08  * /(\s)*([a-zA-Z0-9]+|\W)(\.\.\.)?$/ 正则解析:
09  * (\s)* 0或多个空白
10  * ([a-zA-Z0-9]+|\W) 一个或多个字母数字 或 任意不是字母,数字,汉字的字符
11  * (\.\.\.)? 零个或一个...
12  */

5.简单剪枝

看似结束了,但是如果文本有8000+,但是只需要显示前几行,则只显示100+字呢?

那会由于需要不断截取字符,循环会疯掉。用chrome的调试行数console.time()和console.endTime()测试后发现,如果不优化直接上的话8800字需要17s!

然而这里只需要简单剪枝,就可以保持无论多少文字都几十ms的水平了。

剪枝思考:初步打算用二分法,就是当文本高度大于目标高度2倍,则截断一半文字。然而,再考虑到文本里分为三种:中文字、英文字、字符;一般来说,中文字=2英文字=2字符。因此最坏情况可能前面一半字符全部是英文,后面一半文本全部是中文,这样二分法就会截取到25%的高度,因此考虑到最坏情况,需要3倍才截断。

1 while(dheight*3<this.getFinalStyle("height")){
2 this.setText(str.substring(0,str.length/2));
3 str = this.getText();
4  }

这里剪枝还可以大大优化,欢迎提出宝贵意见~*_*

以上,兼容到IE8+,chrome,firefox,safari,opera。

IE7以下不支持element.prototype的原型链扩展,果断鄙视之。

下载:

mlellipsis.js(完整版带注释:1.70k)

mlellipsis.min.js(压缩版:1.06k)

出处targetkiller 原文点此  http://targetkiller.net/mutiple-line-ellipsis/

【CSS/JS学习】如何实现单行/多行文本溢出的省略(...)

引言: 写前端UI的朋友们也许都遇到过这样的问题:我们需要实现这样一个需求,在一个父级元素中隐藏一个可能过长的文本: http://www.cnblogs.com/penghuwan/p/...
  • sinat_17775997
  • sinat_17775997
  • 2017年04月14日 12:16
  • 1661

多行文本溢出显示省略号(…)全攻略 汇总

1、《CSS3如何实现超出指定文本以省略号显示效果》 原文出处:http://blog.csdn.net/billfeller/article/details/40436491?utm_source...
  • spokenInChina
  • spokenInChina
  • 2015年03月12日 15:22
  • 2558

表格和div中文字溢出隐藏加省略号

表格和div文字溢出隐藏 .container{height:200px;} .top{margin-left:210px;border:2px solid green; height:200...
  • u011647053
  • u011647053
  • 2015年10月14日 16:55
  • 1294

CSS实现单行、多行文本溢出显示省略号(…)

.inaline { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; /*clip 修剪...
  • cometwo
  • cometwo
  • 2016年07月10日 16:14
  • 6349

CSS 单行溢出文本显示省略号...的方法(兼容IE FF)

原文地址:http://www.cnblogs.com/xiaochaohuashengmi/archive/2010/08/06/1793922.html
  • WeLoveSunFlower
  • WeLoveSunFlower
  • 2014年07月21日 10:41
  • 3792

多行文本溢出显示省略号(…)全攻略

掘金是一个高质量的技术社区,从 ECMAScript 6 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货。各大应用市场搜索「掘金」即可下载APP,技术干货尽在掌握.. ...
  • fanhu6816
  • fanhu6816
  • 2016年07月29日 12:56
  • 1970

css控制不溢出,不换行,溢出部分省略号显示

white-space: nowrap;text-overflow:ellipsis; overflow:hidden; text-overflow : clip | ellipsis 取值: cl...
  • u014027705
  • u014027705
  • 2016年08月31日 16:36
  • 2170

微信小程序-----文本溢出

文本溢出是一个非常常见的问题,尤其是在手机端上 这是理想中的状态,但是对于长标题来说,可能就要崩溃了 轻者换行 重者样式崩坏 当一行文字超过了限定范围,就会出现换行等现象,这就叫文...
  • superdog007
  • superdog007
  • 2016年12月05日 16:34
  • 4987

CSS实现单行、多行文本溢出显示省略号(…)

1、单行文本的溢出 overflow: hidden; text-overflow:ellipsis; white-space: nowrap; 2、多行文本的溢出 ...
  • ZHIYUANfL
  • ZHIYUANfL
  • 2017年02月15日 11:09
  • 3347

CSS中span内容超出部分以...显示

使用text-overflow:ellipsis对溢出文本显示省略号有两个好处,一是不用通过程序限定字数;二是有利于SEO。需要使用对对溢出文本显示省略号的通常是文章标题列表,这样处理对搜索引擎更友好...
  • u010688587
  • u010688587
  • 2016年12月15日 17:06
  • 6267
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:mlellipsis.js-实现多行文字溢出隐藏显示省略号
举报原因:
原因补充:

(最多只允许输入30个字)