DOM元素的5种宽高

91 阅读3分钟

为什么专门记?

实际场景并不是简单要知道宽高的值,要灵活使用来优雅地实现业务需求。那么,仅靠需要再去查的方式,是想不到好的解决方案的,还是得理解。

实际场景

场景:在一个需求中,使用了同组封装好的Table组件。默认情况不换行,内容超出时ellipsis(内容被...截断),hover时展示,但会遮挡其他单元格数据。

image.png

element-ui是怎样做的呢?

在element-ui中,单元格会自动换行增加高度,不会产生覆盖、挤压等问题。但是这种做法会使得每行的高度不一致,并不是很棒的操作

image.png

如此常见的场景,element-ui也进行了支持,在el-table-column添加show-overflow-tooltip即可。

image.png

但如果脱离了element-ui,又或者我想使文档超过2行的时候再show-overflow-tooltip怎么办呢?想要按场景自定义,我们就得自己实现这个操作。

目标:超过两行时ellipsis,hover时通过element-ui的tooltip展示全部内容。

实现方式

Google一下"列表组件超出两行显示tooltip,超出文本以...显示"出来一大堆,但解决方式大同小异。

超过两行ellipsis

css就能解决问题,不用傻乎乎的用JS去算

.className {
    display: -webkit-box;
    overflow: hidden;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    width: 180px;
    line-height: 16px;
}

超过两行展示tooltip

网上的实现方式基本统一,基本都是用JS新建元素去算,代码就不贴了。

  1. 监听cell的moverover事件
  2. 创建元素,样式与实际className的一致,但去除overflow: hidden。内容是实际文本。但为了影响页面,记得display: none
  3. appendChild后,拿到这个元素与实际cell的offsetHeight。(不appendChild后拿不到!)
  4. 实际cell高度小于新增元素则视为内容超出,展示tooltip
  5. remove新增元素

新增元素方式真的是最好的吗?

且不说这种做法有多低效,光是写起来就让人不爽了。Vue、React这种框架本身就是为了减少js直接操作DOM,所以心里异常嫌弃。然后继续寻觅,找到一片文章文本溢出与 Tooltip,如何更好的处理二者

this.showTooltip = this.$refs.name.offsetHeight < this.$refs.name.scrollHeight; // 处理多行省略

卧槽,他一行代码解决了,牛皮。

如果不理解scrollHeight根本想不到这种解决办法,光知道scrollHeight是滚动高度没用,还得知道这个值包含了元素的整个overflow,而不是可视区域

那就记一下喏

字段包含特点
clientHeightheight、padding不含boder
offsetHeightheight、padding、boder、水平滚动条常用属性。元素的占地面积
scrollHeightheight、padding、boder、水平滚动条它与offsetHeight的区别在于可以包含了不可见的内容
offsetTop-元素顶部与定位父元素(position不为static)顶部的垂直距离
scrollTop-滚轮滚动的距离,也就是元素可视区域顶部与整体顶部的垂直距离

注:把元素看作一整张报纸,用一个放大镜(没有放大作用,只是形容有个边界)看到的就是可视区域,拖动滚动条相当于移动放大镜。offsetHeight是可是区域的高度,scrollHeight是整张报纸的高度。

overflow: hidden并不影响scrollHeight!