文本省略与tooltip计算展示省略内容研究

204 阅读2分钟

源码:github.com/skylar2826/…

单行文本省略

实现方案

width: 200px; // 未指定宽度,无法确定超过多长进行省略
text-overflow: ellipsis; // 明确文本超出省略;但text-overflow不会触发“溢出”事件
overflow: hidden;
white-space: nowrap; // overflow+white-space触发“溢出”事件

演示

image-20230414155924063.png

多行文本省略

实现方式

width: 200px;
-webkit-line-clamp: 3; // 控制显示行数,-webkit-line-clamp生效需要配置display: -webkit-box || -webkit-inline-box; && -webkit-box-orient:vertical;
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden; // 默认溢出,hidden表示隐藏

演示

默认溢出

image-20230414160713121.png

超出隐藏

image-20230414160751303.png

文本省略搭配tooltip展示研究

QA:如图,表单关键词选择时使用单行文本省略,保证布局展示统一;但超长文本无法看到全部文本信息

image-20230418142824681.png

回复:如图,我们常使用文本省略配合tooltip展示来解决超长文本展示不全的问题

image-20230418143224155.png

优化:如图,使用createRange方法计算宽度,保证仅超长文本展示tooltip,普通文本不展示tooltip

1.gif

核心源码

handleShowTooltip(e, keyword) {
  const { target } = e;
  e.stopPropagation();
  const range = document.createRange();
  range.setStart(target, 0);
  range.setEnd(target, target.childNodes.length);
  // 真实宽度(元素的大小)range.getBoundingClientRect().width,看到的宽度(视口宽度)target.clientWidth
  const rangeWidth = range.getBoundingClientRect().width;
  // 比较元素实际宽度和视口宽度,若实际宽度大于视口宽度则说明进行了文本省略,需要展示tooltip
  const isOverflow = Math.floor(rangeWidth) > target.clientWidth; 
  this.isTooltipList[keyword] = isOverflow;
  this.isTooltipList = JSON.parse(JSON.stringify(this.isTooltipList));
}

range粗解

range表示document片段,使用方式:

let range = document.createRange();
// range.setStart确定片段的开始位置,开始在startNode节点+startOffset(偏移量)的位置
range.setStart(startNode, startOffset); 
range.setEnd(endNode, endOffset); 
/* 注意:offset(偏移量)
 * 若node是文本节点,则偏移量是字数
 * 若node是元素,则偏移量是子节点个数
 */

selection、range、section关系

<section>标签

section和range、selection没有关系,只是单词长得像;

<section>表示HMTL文档中的一个独立章节,当没有合适的标签可以使用了,再用这个标签,一般来说会包含一个标题。比如:

<section>
    <h1>标题</h1>
    <p>内容</p>
</section>

selection与range

selection对象是用户选中的部分,如图;它有锚点(开始位置)、焦点(结束位置)、范围(range)

v2-dc3be19bbddeebcf9b898cd8030b6412_720w.jpeg

let selObj = window.getSelection(); // 拿到selection对象
let range = selObj.getRangeAt(0); // 拿到对应的range对象

相关资料

mdn Selection

关于selection和range的一些认识