文本溢出与 Tooltip,如何更好的处理二者

前言

前端开发中文本溢出是一个非常常见的场景,如果在编程中没有对这部分进行处理,很可能会出现因为文本太长影响整体视觉效果或前端布局的情况。因此,对于有可能出现文本溢出的地方,我们需要对他们进行一些处理。当然,单纯地处理溢出很简单,如果要结合 Tooltip 做一些略复杂的交互显示,可能需要考虑更多的内容,接下来我们来对这些内容逐步的进行探讨:

实现

文本溢出省略的处理方案

目前而言,常见的处理方案可能分为以下几种情况,单行省略处理和多行省略,这部分的 CSS 方案在网上很容易能找得到。话不多少,先扔代码:

  1. 单行省略
1
2
3
4
5
div {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

核心的部分是 text-overflow: ellipsis; 但是有几个需要注意的点:这个属性只对那些在块级元素溢出的内容有效,而且必须要与块级元素内联(inline)方向一致,所以我们还需要加上 white-space: nowrap, 并将 overflow 设置为 hidden 以使得 text-overflow 生效。

  1. 多行省略
1
2
3
4
5
6
div {
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}

这种方式实现的省略可以在文本超出规定行数时超出的部分按照 ...,当时它也只适用于 webkit 内核的浏览器。非 webkit 内核的实现方案需要用伪元素或 float 的方式来实现,这里我们不做讨论,感兴趣的朋友可以参考这篇博客

Tooltip 结合 ellipsis

关于 tooltip 的实现本文不做探讨,我们采用 Element 中的 Tooltip 作为示例进行演示:

阶段 1

首先来进行暴力拼接,将文本的全部内容直接进行 Tooltip 显示而不用管是否会触发超出省略:

1
2
3
<el-tooltip :content="content">
<div class="ellipsis-item">{{ content }}</div>
</el-tooltip>

实现的内容大概是这个样子的:
image

但是这显然不是一个很好的解决方案,对于那些并没有溢出的文本,每次 hover 上去时还会显示 Tooltip,实在是一种糟心的体验。因此我们需要对上面的内容进行一些优化。

阶段 2

这次我们要实现一个文本溢出时 hover 显示 Tooltip,不溢出时 hover 不显示的效果。但是我们在第一步文本溢出的配置中是用 css 来进行设置的,如何才能通过 JS 来控制什么显示 Tooltip 的时机呢?这就要从文本溢出的原理讲起了:

我们知道,每一个 HTML 元素都具有:clientHeight(clientWidth)offsetHeight(offsetWidth)scrollHeight(scrollWidth)offsetTop(offsetLeft)scrollTop(scrollLeft) 五种类型的属性,他们分别表示:

  • clientHeight(clientWidth): 对象内容的可视区的高度(宽度)。包括 padding 但不包括 border、水平滚动条、margin 的元素的高度(宽度)。对于 inline 的元素这个属性一直是 0
    image
  • offsetHeight(offsetWidth): 对象整体的实际高度(宽度)。包括 padding、border、水平滚动条,但不包括 margin 的元素的高度(宽度)。对于inline的元素这个属性一直是 0,单位 px。
    image
  • scrollHeight(scrollWidth): 对象的实际内容的高度(宽度)。当实际内容超出可视区时会通过出现滚动条,通过滚动条可以调节实际内容在可视区的显示部分。

  • scrollTop(scrollLeft): 在有滚动条时,滚动条向下(向右)滚动的距离也就是元素顶部(左侧)被遮住部分的高度(宽度)。

  • offsetTop(offsetLeft): 当前元素顶部(左侧边框)距离最近的定位父元素顶部(左侧边框)的距离。
    image

对于单行省略而言:当文本所在的块元素的实际宽度超过了可视区的宽度(即 scrollWidth 超过了 clientWidth),那么就会被判定为文本超出,我们就可以看见熟悉的 ... 了。

同样的道理,对于多行省略而言:文本检测超长的方式并不是 inline 的方向,而是垂直方向,所以我们同理变换即可理解,也就是说,党文在所在快元素的实际高度超过了可视区的高度(即 scrollHeight 超过了 clientHeight),那么就会被判定为文本超出。

根据以上部分的原理,我们可以很容易的实现文本超长 hover 时显示 tooltip,而不超长时候不作处理的方法:

1
2
3
4
5
6
7
8
<el-tooltip v-if="showTooltip" :content="content">
<div ref="content" class="ellipsis-item">{{ content }}</div>
</el-tooltip>

<div v-else ref="content" class="ellipsis-item">{{ content }}</div>

this.showTooltip = this.$refs.content.offsetWidth < this.$refs.content.scrollWidth || // 处理单行省略
this.$refs.name.offsetHeight < this.$refs.name.scrollHeight; // 处理多行省略

所以一些看似比较复杂的应用场景其实都是基本的原理拼接而成的,我们在了解这些原理之后便可以举一反三玩出很多的花样来。就这么简单~

参考资料:
http://imweb.io/topic/57c5409e808fd2fb204eef52
https://www.w3.org/TR/cssom-view

-------------本文结束感谢您的阅读-------------

本文标题:文本溢出与 Tooltip,如何更好的处理二者

文章作者:yangpu

发布时间:2019年06月03日 - 15:27

最后更新:2019年06月03日 - 15:27

原始链接:https://mongofeng.github.io/2019/06/03/ellpise/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。