网站首页 > 技术文章 正文
最近遇到一个问题,计算滚动距离,滚动比例达到某界定值时,显示mask,很常见吧^ _ ^
这里讲的不是这个需求的实现,是其中遇到了一个比较有意思的bug,靠这个bug才达到了正确效果,以及这个bug是如何暴露的(很重要)。
下面是演示代码和动图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
width: 300px;
max-height: 300px;
background-color: black;
position: absolute;
top: 60px;
left: 50%;
transform: translateX(-50%);
overflow-y: auto;
}
.child {
width: 260px;
height: 600px;
margin: 0px 20px;
background-color: pink;
position: relative;
}
.flag {
position: absolute;
width: 100%;
height: 25px;
background-color: blueviolet;
color: aliceblue;
text-align: center;
line-height: 25px;
font-size: 14px;
left: 0;
right: 0;
}
.top {
top: 0;
}
.bottom {
bottom: 0px;
}
</style>
</head>
<body>
<div class="container">
<div class="child">
<div class="flag top">top</div>
<div class="flag bottom">bottom</div>
</div>
</div>
</body>
</html>
开始计算啦,公式:滚动比例 = 滚动距离 / 可滚动距离
滚动距离: $0.scrollTop
可滚动距离: $0.scrollHeight - $0.offsetHeight
即:scrollRatio = scrollTop / (scrollHeight - offsetHeight)
滚动到底部,计算结果是 300 / (600 - 300) = 1
我们需要拿scrollRatio和某界定值(比如0.1)作大小的比较,计算是true还是false(用isShow = scrollRatio < 某界定值来保存)。
这里一切正常。
不正常的情况出现了
就是没有出现滚动条的情况,即.child的高度没有超过.container的高度时,把.child的高度设成.container的max-height,就没有滚动条了(下面讲的情景也都是没有滚动条的情况)。
这个时候再去计算,得到了NaN,以至于 NaN < 0.1 = false。
因为isShow的预期就是false,所以一直都没有发现这个bug。
那么它是如何暴露的呢?
后来新的需求给.container加了border。演示一下加border,然后再去计算:
发现没,这时候$0.offsetHeight的高度把border的高度也算进去了,结果就成了true,这不是想要的结果 。
然后就是一番查验
offsetHeight是一个元素的总高度,包括可见内容的高度、内边距(padding)、滚动条的高度(如果存在)以及边框(border)的高度。
而我们这里只需要可见的高度,就可以用到另一个属性了clientHeight。
clientHeight是指元素的可见内容区域的高度,不包括滚动条的高度和边框的高度。它仅包括元素的内部空间,即内容加上内边距。
当然这也只是继续使除数为0,然后得到结果为NaN,不过bug已经暴露出来了,后面就是一些其他的优化啦~
总结 + 复习(盒模型 box-sizing)
发现没有,offsetHeight和clientHeight的区别,就像盒模型中的标准盒模型和怪异盒模型的区别:
box-sizing: content-box(默认,标准盒模型):宽度和高度的计算值都 不包含 内容的边框(border)和内边距(padding)。添加padding和border时, 会 使整个div的宽高变大。
box-sizing: border-box(怪异盒模型):宽度和高度的计算值都 包含 内容的边框(border)和内边距(padding)。添加padding和border时, 不会 使整个div的宽高变大。
这样讲是不是加深一下对这两种属性的印象
作者:aomyh
链接:
https://juejin.cn/post/7283087306603823116
猜你喜欢
- 2025-09-21 破解小程序开发陷阱:这7个坑90%企业都踩过(附避坑指南)
- 2025-09-21 分享7个 Python CLI 库,助您快速构建高效命令行应用程序
- 2025-09-21 作为一名前端,是怎么理解nginx的
- 2025-09-21 《开源AIRemoveBackground:用 AI 技术轻松去除背景图的前端程序》
- 2025-09-21 HTTrack V3.49-2:专业级前端仿站程序,实现网站本地镜像构建
- 2024-12-14 看完让你彻底理解 WebSocket 原理,附完整的实战代码(包含前端和后端)
- 2024-12-14 程序猿何苦为难程序猿:前端与后端不得不说的密码
- 2024-12-14 开发一个小程序需要多长的时间?
- 2024-12-14 前端开发79条知识点汇总
- 2024-12-14 详细解读小程序的构成,看完你就全部懂了
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- oracle面试 (55)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)