文本溢出时出现...,如何判断文本是否溢出?

1,070 阅读3分钟

此篇文章只是个人见解,仅供参考。

一、判断多行文本溢出

示例:div文本最多显示2行,溢出后显示...,如何判断文本溢出?

<!DOCTYPE html>
<html>
<head>
<style>
.text-clamp {  
  display: -webkit-box;  
  -webkit-box-orient: vertical;  
  -webkit-line-clamp: 2; /* 限制显示的行数 */  
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.5;
  word-break: break-word;
  padding: 0 16px;
}
</style>
</head>
<body>

<div class="text-clamp">
<span>这是一段示例文本,用来展示如何在CSS中限制文本最多显示2行,并且超出部分用省略号表示。注意,这个效果依赖于WebKit的私有属性,因此在非WebKit浏览器中可能无法正常工作。</span>
</div>
</body>
</html>

显示效果: image.png

可通过比较div元素的clientHeight和scrollHeight来判断是否溢出。

scrollHeight > clientHeight,文本溢出。

没有溢出:

image.png 溢出:

image.png

注:

设置上下padding会影响溢出显示,如下图所示:

image.png

二、判断单行文本溢出

思考:可以通过scrollWidth和clientWidth比较判断吗?答案:不行

主要思路:将盒子改成行盒布局,即display: inline,这样就不会溢出,然后通过web提供的api getBoundingClinetRect()获取两个元素的width进行比较,如果新元素的width大于原元素的width,则文本溢出。

示例:

<!DOCTYPE html>
<html>
<head>
<style>
.text-clamp {
  white-space: nowrap; 
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 16px;
}
</style>
</head>
<body>

<div class="text-clamp">
这是一段示例文本,用来展示单行文本溢出,并且超出部分用省略号表示haole
</div>
</body>
</html>

image.png 这里我搞了一个刚好溢出的极限场景,此时控制台$0.getBoundingClientRect().width宽度为586。

现在将div的display改成inline: image.png 文本没有溢出,此时宽度变成了586.203125,说明此方法有效。

回答思考的问题

1、为什么不能通过直接比较盒子的scrollWidth和clientWidth判断溢出?

scrollWidth虽然包含了文本溢出的内容宽度。但是,scrollWidth和clientWidth都是通过浏览器样式计算得到的,都是整数,是盒子真实宽度进行四舍五入的结果,因此不精确。

极限场景:刚好溢出时,两者相同。非极限场景可以。如下图:

极限场景:

image.png 非极限场景:

image.png

三、总结

首先,不管是多行溢出还是单行溢出,都是针对块盒模型,行盒模型(display为inline)是不会有此种场景的。因为溢出是由盒子的宽高决定的,盒子宽高容纳不下才会出现溢出,行盒不能设置宽高,因此行盒不会出现文本溢出。

1. 判断多行文本溢出

scrollHeight > clientHeight,溢出。

原理:

多行文本溢出出现...时,说明一定出现了换行,没有溢出时的盒子高度一定大于溢出时高度。因此可以利用这两个属性进行比较。

scrollHeight:表示元素内容高度,包括由于溢出导致的视图中不可见的部分。

clientHeight:表示元素内容可见视口的高度,包括padding。

所以,只要溢出,scrollHeight一定会大于clientHeight。

2. 判断单行文本溢出

通过getBoundingClientRect()获取溢出和非溢出时的width进行比较。

原理:

没有溢出的宽度一定大于溢出时宽度。现在问题在于如何获取盒子没有溢出时的宽度,此时可以利用行盒模型的特性,行盒盒子不会溢出,通过getBoundingClientRect()可获取到其在视口上的宽度。