摘要:如果段落高度小于给定高度,则不限制最大高度,隐藏展开按钮。但如何计算段落高度小于给定高度呢比如,段落被设置了,如何计算它的真实高度呢二干货,计算元素真实高度函数方法如下,直接传入要计算的目标就好了。
一、问题背景假设,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/51242.html
摘要:如果段落高度小于给定高度,则不限制最大高度,隐藏展开按钮。但如何计算段落高度小于给定高度呢比如,段落被设置了,如何计算它的真实高度呢二干货,计算元素真实高度函数方法如下,直接传入要计算的目标就好了。 假设,DOM 被设置了 height:20px 和 overflow:hidden,如何计算它的真实高度呢? 一、问题背景 最近在优化折叠组件,需要在窗口宽度变化的时候重新判断展开收起状态...
摘要:移动端导航栏有个很常见的折叠菜单,有插件实现,有组件。最近用无插件实现一个这样的效果。探究历程直接采用,虽然实现了控制容器的显示和隐藏,但是效果生硬。 移动端导航栏有个很常见的折叠菜单,bootstrap有collapse插件实现,jQuery UI有Accordion组件。最近用js无插件实现一个这样的效果。 探究历程 display:none; 直接采用display,虽然实现...
摘要:移动端导航栏有个很常见的折叠菜单,有插件实现,有组件。最近用无插件实现一个这样的效果。探究历程直接采用,虽然实现了控制容器的显示和隐藏,但是效果生硬。 移动端导航栏有个很常见的折叠菜单,bootstrap有collapse插件实现,jQuery UI有Accordion组件。最近用js无插件实现一个这样的效果。 探究历程 display:none; 直接采用display,虽然实现...
摘要:需求很简单,而且和知乎的显示全部收起功能非常相似,但是了一下没有找到类似的,因此决定自己实现一个看了知乎的网页代码。 showImg(https://segmentfault.com/img/remote/1460000008488966);showImg(https://segmentfault.com/img/remote/1460000008488967); Update 20...
摘要:需求很简单,而且和知乎的显示全部收起功能非常相似,但是了一下没有找到类似的,因此决定自己实现一个看了知乎的网页代码。 showImg(https://segmentfault.com/img/remote/1460000008488966);showImg(https://segmentfault.com/img/remote/1460000008488967); Update 20...
阅读 1518·2023-04-25 17:41
阅读 3040·2021-11-22 15:08
阅读 842·2021-09-29 09:35
阅读 1604·2021-09-27 13:35
阅读 3322·2021-08-31 09:44
阅读 2715·2019-08-30 13:20
阅读 1937·2019-08-30 13:00
阅读 2556·2019-08-26 12:12