前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >clientWidth,offsetWidth,scrollWidth你分的清吗

clientWidth,offsetWidth,scrollWidth你分的清吗

作者头像
Jou
发布2022-11-12 13:53:07
1.9K0
发布2022-11-12 13:53:07
举报
文章被收录于专栏:前端技术归纳前端技术归纳

前言

最近在开发时遇到这样一个需求,一个表单列表报错后,滚动表单到能展示报错元素,做的时候发现clientWidth,offsetWidth,scrollWidth这几个概念自己有时候还是会弄混,所以想写篇文章记录一下。

clientWidth/clientHeight

clientHeight和clientWidth计算时包含元素的content,padding

不包括border,margin和滚动条占用的空间。对于inline的元素这个属性一直是0

图片.png
图片.png

offsetWidth/offsetHeight

offsetWidth/offsetHeight计算时包含 content + padding + border

不包括margin的元素的高度。对于inline的元素这个属性一直是0

offsetTop/offsetLeft/offsetRight/offsetBottom:

代表元素距离父级元素的相对距离,但是父级元素需要具有relative定位,直到找到body,并且即使元素会被滚动,这个值也不会改变

图片.png
图片.png

scrollWidth/scrollHeight

scrollWidth/scrollHeight 返回值包含 content + padding + 溢出内容的尺寸,这个只针对dom的子元素出现溢出情况时,才有效果,不然它始终和clientHeight相等

scrollTop

代表在有滚动条时,滚动条向下滚动的距离也就是元素顶部被遮住部分的高度。在没有滚动条时scrollTop==0。

图片.png
图片.png

getBoundingClientRect()

它返回一个对象,其中包含了left、right、top、bottom四个属性,分别对应了该元素的左上角和右下角相对于浏览器窗口(viewport)左上角的距离

注意:当元素溢出浏览器的视口,值会变成负数。

但是滚动元素是从可视区域的左上角和右下角开始计算,如果想获取滚动元素整体的坐标,需要加上滚动距离

代码语言:javascript
复制
 var X = node.getBoundingClientRect().left+node.scrollLeft;

 var Y = node.getBoundingClientRect().top+node.scrollTop;

一个demo加深印象

有一个列表,当我们输入文段编号,列表会将选中文段滚动到视图中

大概是这样

preview.gif
preview.gif

实现思路就是,去拿到选中元素的clientHeightoffsetTop,并和列表的高度区间做比较,计算出元素是在列表视口的内部,还是溢出的视口,如果溢出了视口,那么就回滚。

笔者用react写的,直接附上代码吧

dom

代码语言:javascript
复制
<div className='container'>
    <div className='scroll' ref={(ref) => (this.scrollRef = ref)}>
        {new Array(15).fill(0).map((_item, index) => (
          <p
            key={index}
            ref={(ref) => (this.pRef[`ref${index}`] = ref)}
            style={{ backgroundColor: Number(el) === index ? 'red' : '' }}
          >{`这是第${index}文段`}</p>
        ))}
    </div>
  </div>

less

代码语言:javascript
复制
.container{
    height: 340px;
    width: 500px;
    margin: auto;
    margin-top: 100px;
    border:1px black solid;
    overflow: hidden;
    padding: 10px;
    position: relative;
    display: flex;
    align-items: center;
    justify-content:space-between;
    flex-direction: column;
}
.scroll{
  height: 300px;
  width: 500px;
  overflow-y: scroll;
  border:1px solid orange;

  p{
    text-align: center;
    font-size:22px;
    color:#9ef64d;
  }

核心方法

代码语言:javascript
复制
const { value } = this.state;
// 滚动视口的高度
const containerHeight = this.scrollRef.clientHeight;
// 滚动视口距离浏览器顶部的距离
const containerOffsetTop = this.scrollRef.getBoundingClientRect().top;

// 选中元素距离浏览器的高度
const { top } = this.pRef[`ref${value}`].getBoundingClientRect();

// needScroll就是元素底部距离滚动容器顶部的距离,再减去20像素,保证出现在视口中间
const needScroll = top - containerOffsetTop - 20;

if (needScroll > containerHeight || needScroll < 0) {
  // 将选中元素放入容器视口中
  const timer = setTimeout(() => {
    this.scrollRef.scrollTop = this.scrollRef.scrollTop + needScroll;
    clearTimeout(timer);
  }, 0);
}

最后

本文整理了clientWidth,offsetWidth,scrollWidth的概念,以及它们所衍生出来的offsetTop,scrollTop的使用,并加上了一个不算复杂的demo,希望能对你有用,当然,如果可以,笔者也希望你能点个赞再走呢

参考链接

https://www.ruanyifeng.com/blog/2009/09/find_element_s_position_using_javascript.html

https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • clientWidth/clientHeight
  • offsetWidth/offsetHeight
    • offsetTop/offsetLeft/offsetRight/offsetBottom:
    • scrollWidth/scrollHeight
      • scrollTop
      • getBoundingClientRect()
      • 一个demo加深印象
      • 最后
        • 参考链接
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档