资讯专栏INFORMATION COLUMN

获取height固定折叠元素真实高度方法

gaomysion / 1825人阅读

摘要:如果段落高度小于给定高度,则不限制最大高度,隐藏展开按钮。但如何计算段落高度小于给定高度呢比如,段落被设置了,如何计算它的真实高度呢二干货,计算元素真实高度函数方法如下,直接传入要计算的目标就好了。

假设,DOM 被设置了 height:20px 和 overflow:hidden,如何计算它的真实高度呢?

一、问题背景

最近在优化折叠组件,需要在窗口宽度变化的时候重新判断展开收起状态。如果段落高度大于给定高度,则隐藏超高内容,展示【展开】按钮。如果段落高度小于给定高度,则不限制最大高度,隐藏【展开】按钮。

但如何计算【段落高度小于给定高度】呢?比如,段落被设置了 height="20px",如何计算它的真实高度呢?

二、干货,计算元素真实高度函数

方法如下,直接传入要计算的目标 dom 就好了。

function getHeightUnfold (dom) {
    var fakeNode = dom.cloneNode(true);
    fakeNode.style.position = "absolute";
    // 先插入再改样式,以防元素属性在createdCallback中被添加覆盖
    dom.parentNode.insertBefore(fakeNode, dom);
    fakeNode.style.height = "auto";
    fakeNode.style.visibility = "hidden";

    var height = fakeNode.getBoundingClientRect().height;
    dom.parentNode.removeChild(fakeNode);

    return height;
}

这个方法的核心是,创建一个不可见元素,摘除高度限制,最终计算它的高度。

三、发散思考 1. 复制元素的必要性

Jenny_L 给复制出来的元素增加了 postiion: absolute 属性,为了不触发后面元素的重拍重绘,节省浏览器资源。如果直接快速地给目标元素设置 height: auto + 获取高度 + height: 20px,虽然能达到目的,但会造成所有后续元素的(不一定可见)抖动,尽量避免。

2. Node.cloneNode 与 document.createElement("div") 的选择

后者与innerHTML配合使用,虽然能够模仿目标元素的内层内容,但不能继承目标元素的样式。即使使用document.createElement(dom.nodeName)也会有问题,不能继承内联样式。而使用cloneNode不但可以继承 class,css,还能触发 createdCallback(如果有的话),继承 js 中添加的内联样式。

3. fakeNode.getBoundingClientRect().height 与 getComputedStyle(fakeNode).height 的选择

都是计算高度的,但前者计算的是占位高度,包括 padding+border;后者计算的是单纯高度,经过多层 css 优先级竞争之后的 height 取值(px),获取纯数值还需要parseInt()。本次情况,需要计算占位高度,所以选择getBoundingClientRect()

4. removeChild 的必要性

虽然 fakeNode 不可见,但终究在文档流中,display 不是 none,重拍的时候会参与计算。除此之外,如果原先 dom 带有 id="someID" 的话,删除 fakeNode 之前,文档中就会存在两个 id="someID" 的元素。未来浏览器再做选择的时候,就懵逼了。

四、自勉

好久不写文章了,草稿箱里存了好多代码片段,要加油了。

不得不说,这种小代码片段还是很有分享价值的,一次研究(竟然花了一个小时),未来处处复制,走向人生巅峰。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88439.html

相关文章

  • 获取height固定折叠元素真实高度方法

    摘要:如果段落高度小于给定高度,则不限制最大高度,隐藏展开按钮。但如何计算段落高度小于给定高度呢比如,段落被设置了,如何计算它的真实高度呢二干货,计算元素真实高度函数方法如下,直接传入要计算的目标就好了。 假设,DOM 被设置了 height:20px 和 overflow:hidden,如何计算它的真实高度呢? 一、问题背景 最近在优化折叠组件,需要在窗口宽度变化的时候重新判断展开收起状态...

    lingdududu 评论0 收藏0
  • js轻松实现折叠面板

    摘要:移动端导航栏有个很常见的折叠菜单,有插件实现,有组件。最近用无插件实现一个这样的效果。探究历程直接采用,虽然实现了控制容器的显示和隐藏,但是效果生硬。 移动端导航栏有个很常见的折叠菜单,bootstrap有collapse插件实现,jQuery UI有Accordion组件。最近用js无插件实现一个这样的效果。 探究历程 display:none; 直接采用display,虽然实现...

    suxier 评论0 收藏0
  • js轻松实现折叠面板

    摘要:移动端导航栏有个很常见的折叠菜单,有插件实现,有组件。最近用无插件实现一个这样的效果。探究历程直接采用,虽然实现了控制容器的显示和隐藏,但是效果生硬。 移动端导航栏有个很常见的折叠菜单,bootstrap有collapse插件实现,jQuery UI有Accordion组件。最近用js无插件实现一个这样的效果。 探究历程 display:none; 直接采用display,虽然实现...

    gghyoo 评论0 收藏0
  • 用原生 js && jquery 实现知乎收起答案功能

    摘要:需求很简单,而且和知乎的显示全部收起功能非常相似,但是了一下没有找到类似的,因此决定自己实现一个看了知乎的网页代码。 showImg(https://segmentfault.com/img/remote/1460000008488966);showImg(https://segmentfault.com/img/remote/1460000008488967); Update 20...

    brianway 评论0 收藏0
  • 用原生 js && jquery 实现知乎收起答案功能

    摘要:需求很简单,而且和知乎的显示全部收起功能非常相似,但是了一下没有找到类似的,因此决定自己实现一个看了知乎的网页代码。 showImg(https://segmentfault.com/img/remote/1460000008488966);showImg(https://segmentfault.com/img/remote/1460000008488967); Update 20...

    Seay 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<