【转】理清client-*,scroll-*,offset-*

这篇文章虽然是转发的,但是看完感觉能够有效的帮助理解这3个属性的区别,什么时候该用什么属性,而不是猜测乱用。


offsetWidth offsetHeight offsetLeft offsetTop
clientWidth clientHeight clientLeft clientTop
scrollWidth scrollHeight scrollLeft scrollTop

是时候谈谈它们之间的区别了,是不是已经混乱了?好吧,一步一步来搞清楚这些东西是啥。

终于下决心来补上这个坑,俗话说的话:纸上得来终觉浅,绝知此事要躬行。要搞清这几个容易混淆的概念,我的建议是运行文章中的例子。

offset


offsetWidth & offsetHeight

任何HTML元素的只读属性offsetWidth和offsetHeight已CSS像素返回它的屏幕尺寸,返回的尺寸包干元素的边框和内边距(width/height + border + padding),和滚动条

offsetLeft & offsetTop

所有HTML元素拥有offsetLeft和offsetTop属性来返回元素的X和Y坐标

  1. 相对于已定位元素的后代元素和一些其他元素(表格单元),这些属性返回的坐标是相对于祖先元素
  2. 一般元素,则是相对于文档,返回的是文档坐标

offsetParent属性指定这些属性所相对的父元素,如果offsetParent为null,则这些属性都是文档坐标

//用offsetLeft和offsetTop来计算e的位置
function getElementPosition(e){
    var x = 0,y = 0;
    while(e != null) {
        x += e.offsetLeft;
        y += e.offsetTop;
        e = e.offsetParent;
    }
    return {
        x : x,
        y : y
    };
}

client


client是一种间接指代,它就是web浏览器客户端,专指它定义的窗口或视口。

clientWidth & clientHeight

clientWidth和clientHeight类似于offsetWidth和offsetHeight,不同的是不包含边框大小(width/height + padding)。同时在有滚动条的情况下,clientWidth和clientHeight在其返回值中也不包含滚动条。

对于类似<i>、<code>、<span>等内联元素,总是返回0

clientLeft & clientTop

返回元素的内边距的外边缘和他的边框的外边缘的水平距离和垂直距离,通常这些值就等于左边和上边的边框宽度。

在有滚动条时,并且浏览器将这些滚动条放置在左侧或顶部(反正我是没见过),clientLEft和clientTop就包含这些滚动条的宽度。

scroll


scrollWidth & scrollHeight

这两个属性是元素的内容区域加上内边距,在加上任何溢出内容的尺寸.

因此,如果没有溢出时,这些属性与clientWidth和clientHeight是相等的。

scrollLeft & scrollTop

指定的是元素的滚动条的位置

scrollLeft和scrollTop都是可写的属性,通过设置它们来让元素中的内容滚动。

width和height计算实例
在这个实例中,我们观察#inner实例,看看该元素各个属性之间的关系

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
     #wrap {
        border : 3px solid red;
        width: 600px;
        height : 600px;
        margin : 50px auto;
    }
    #inner {
        padding : 100px;
        width: 300px;
        height:200px;
        margin:50px auto;
        border:20px solid blue;
        overflow: auto;
    }
    #content{
        width: 200px;
        height:800px;
        border:1px solid black;
      }
    </style>
</head>
<body>
    <div id="wrap">
        <div id="inner">
            <div id="content"></div>
        </div>
    </div>
</body>
</html>

图片描述
在这里插入图片描述


var inner = document.getElementById('inner');
var content = document.getElementById('content');
//辅助变量,获取元素的宽和高
var style = getComputedStyle(inner);

//width & height
console.log('width= '+style.width);// ''
console.log('height= ' + style.height);// ''

//padding
console.log('paddingt-top='+style.paddingTop);
console.log('paddingt-bottom= '+style.paddingBottom);
console.log('paddingt-left= '+style.paddingLeft);
console.log('paddingt-right= '+style.paddingRight);

//border
console.log('border-top-width= '+style.borderTopWidth);
console.log('border-bottom-width= '+style.borderBottomWidth);
console.log('border-left-width= '+style.borderLeftWidth);
console.log('border-right-width= '+style.borderRightWidth);

//offsetWidth & offsetWidth
console.log('offsetWidth= '+inner.offsetWidth);
console.log('offsetHeight= '+inner.offsetHeight);

//clientWidth & clientHeight
console.log('clientWidth= '+inner.clientWidth);
console.log('clientHeight= '+inner.clientHeight);

// scrollWidth & scrollHeight
console.log('scrollWidth= '+inner.scrollWidth);
console.log('scrollHeight= '+inner.scrollHeight);

// #content.offsetHeight
console.log('#content.offsetHeight= '+content.offsetHeight);
由于元素是外链的样式,没有设置style,因此如果直接使用inner.style.width返回的是空。必须使用getComputedStyle(el)来获取元素的宽和高

图片描述
在这里插入图片描述
说明:

宽度

width:本来应该是300,但是由于存在滚动条(在水平方向占据了空间),因此

原本内容区宽度(width) - 滚动条宽度 = 300 - 17 = 283

offsetWidth:元素实际所占空间,滚动条也是元素占据的空间,因此

width + 滚动条 + padding + border = 300 + 100 + 100 + 20 + 20 = 540

clientWidth:除去边框占据的空间,且不包含滚动条

width + padding = 283 + 100 + 100 = 483

scrollWidth:由于水平方向没有溢出,因此

clientWidth + 溢出部分 = 483 + 0 = 483

高度

height:由于垂直方向没有滚动条占据空间,因此

原本内容区高度(height)- 滚动条高度 = 200 - 0 = 200

offsetHeight:元素实际所占空间,由于采取了滚动的方式处理了溢出的部分,因此

height + padding + border = 200 + 100 + 100 + 20 + 20 = 440

clientHeight:

height + padding = 200 + 100 + 100 = 400

scollHeight:客户区高度,加上溢出的部分,即包含元素真实高度-内容区的高度

height+padding+(#content.offsetHeight-height)=200+100+100+802-200=1002

left和top实例
html结构与上一个实例一直。这样可以

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
     #wrap {
        border : 3px solid red;
        width: 600px;
        height : 600px;
        margin : 50px auto;
        position:relative;
    }
    #inner {
        padding : 100px;
        width: 300px;
        height:200px;
        margin:50px auto;
        border:20px solid blue;
        overflow: auto;
    }
    #content{
        width: 200px;
        height:800px;
        border:1px solid black;
      }
    </style>
</head>
<body>
    <div id="wrap">
        <div id="inner">
            <div id="content"></div>
        </div>
    </div>
</body>
</html>

分别获取属性

var inner = document.getElementById('inner');

//offsetLeft & offsetTop
console.log("offsetLeft= "+inner.offsetLeft);
console.log("offsetTop= "+inner.offsetTop);

//clientLeft &  clientTop
console.log("clientLeft= "+inner.clientLeft);
console.log("clientTop= "+inner.clientTop);

// scrollLeft & scrollTop
console.log("scrollLeft= "+inner.scrollLeft);
console.log("scrollTop= "+inner.scrollTop);

//让文档滚动
inner.scrollTop = 30;

//为了计算的方便
var style = getComputedStyle(inner);

图片描述
在这里插入图片描述
分析:

(#wrap为参照原点,设置了position:relative)

offsetLeft:即元素的x坐标,(#inner设置了自动居中)

offsetLeft = (#wrap.width - #inner.offsetWidth)/2 =30

offsetTop:即元素的y坐标,(style是#inner元素的计算后的样式)

offsetTop = style.marginTop = 50

clientLeft 即 border-left-width

clientLeft = style.borderLeftWidth = 20

clientTop 即 border-top-width

clientTop = style.borderTopWidth = 20

scrollLeft 由于水平方向没有滚动条,因此为0

scrollTop 即滚动条离#inner border-top内侧的位置,一开始为0

此文章转自:https://segmentfault.com/a/1190000005897042

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值