目录
前言
之前看到三大家族这四个字,我还在想这是啥,有这么高级的名字,后来发现JS的三大家族原来就是 offset 、 scroll 、 client 这三个家族。
例如我之前写过的JavaScript实现的电子时钟就用到了它们,我们可以通过这三大家族模拟出很多酷炫的JS动画,增强界面的视觉感染力,让静态页面活起来。下面将分别为大家介绍这三个家族。
一、offset家族
offsetWidth和offsetHeight
用来获取对象自身的宽度和高度,包括内容、边框、内边距。
offsetWidth = width + border + padding
offsetHeight = height + border + padding
例:
<style>
#div1{
width: 200px;
height: 180px;
border: 15px solid blue;
padding: 10px;
background-color: hotpink;
margin: 40px;
}
</style>
<body>
<div id="div1"></div>
<div id="div2" style="width: 200px;height: 180px;"></div>
<script>
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2")
console.log("div1的offsetWidth和offsetHeight分别是:"+div1.offsetWidth,div1.offsetHeight);
console.log("div1样式的width和height分别是:"+div1.style.width,div1.style.height);
console.log("div2样式的width和height分别是:"+div2.style.width,div2.style.height);
</script>
</body>
计算得:
div1.offsetWidth = 200 + 15×2 + 10×2 = 250
div1.offsetHeight = 180 + 15×2 + 10×2 = 230
运行结果是:
这时,我们发现div1.style.width和div1.style.height没有输出结果,而div2.style.width和div2.style.height有输出结果,这是因为使用div1.style.width和div1.style.height获取宽度和高度的时候,只能获取到行内定义的width。
offsetLeft和offsetTop
返回距离第一个有定位的父级盒子左边/上边的距离。
注意:
- 如果父级都没有定位的话则以body为准。
- 这里距离父级盒子左边/上边是从父盒子的padding位置开始算的,父盒子的border不计算在内。也就是说,offsetLeft和offsetTop就是子盒子到最近的带有定位的父盒子边框到边框的距离。
例:
<style>
#father1{
width: 450px;
height: 350px;
padding: 10px;
border: 5px solid blue;
background-color: cadetblue;
margin: 50px;
}
#father2{
width: 300px;
height: 250px;
border: 5px solid yellow;
padding: 10px;
background-color: lightsalmon;
margin-left: 50px;
margin-top: 40px;
}
#son{
width: 200px;
height: 180px;
background-color: lightgreen;
border: 10px solid red;
margin-left: 40px;
margin-top: 30px;
}
</style>
<body>
<div id="father1">
<div id="father2">
<div id="son"></div>
</div>
</div>
<script>
var father1 = document.getElementById("father1");
var father2 = document.getElementById("father2");
var son = document.getElementById("son");
console.log("son的offsetLeft和offsetTop是:"+son.offsetLeft,son.offsetTop)
</script>
</body>
运行结果如下:
可以看出,若父盒子都没有定位的话,得到的距离是以body为准的。
如果我们给 #father1父盒子 样式中添加一句 position: relative;
son.offsetLeft = 40 + 10 + 5 + 50 + 10 = 115
son.offsetTop = 30 + 10 + 5 + 40 +10 = 95
结果如下:
如果我们给 #father2父盒子 样式中添加一句 position: relative;
son.offsetLeft = 40 + 10 = 50
son.offsetTop = 30 + 10 = 40
结果如下:
offsetParent
返回当前对象的最近的带有定位的父级盒子。
例(还是用上面那个例子):
<style>
#father1{
width: 450px;
height: 350px;
padding: 10px;
border: 5px solid blue;
background-color: cadetblue;
margin: 50px;
position: relative;
}
#father2{
width: 300px;
height: 250px;
border: 5px solid yellow;
padding: 10px;
background-color: lightsalmon;
margin-left: 50px;
margin-top: 40px;
position: relative;
}
#son{
width: 200px;
height: 180px;
background-color: lightgreen;
border: 10px solid red;
margin-left: 40px;
margin-top: 30px;
}
</style>
<body>
<div id="father1">
<div id="father2">
<div id="son"></div>
</div>
</div>
<script>
var son = document.getElementById("son");
console.log("son的offsetParent是:",son.offsetParent)
</script>
</body>
运行结果如下:
offsetxxx和style.xxx的区别
(以offsetLeft和style.left为例分析)
- style.left只能获取行内设置样式的值,而offsetLeft则可以获取到所有的。
- offsetLeft可以返回没有定位的盒子距离左边的距离,而style.left不能,因为只有定位的元素才有left的值。
- offsetLeft返回的是一个number类型的数子,不带单位,而style.left返回的是带单位的字符串。
- offsetLeft是只读属性,而style.left是可读写的。
- 如果没有给元素指定left样式,style.left返回的是空字符串,而offsetLeft只能是数字。
二、scroll家族
scrollWidth和scrollHeight
scrollWidth / scrollHeight = 元素自身的宽高 + padding
注意:不包含元素的border
scrollLeft和scrollTop
- 返回当你滑动滚轮浏览网页的时候网页隐藏在屏幕上方的距离(如图),也可以用来指定元素的滚动条的位置。
- scrollLeft和scrollTop是可写的,可以通过设置它们来让元素中的内容滚动。
scroll事件(滚动事件)
element.onscroll = function(){页面滚动语句}
scrollTo(x,y)
- 把内容滚动到指定的坐标。
- 格式:scrollTo(xpos,ypos)
- xpos 必需:要在窗口文档显示区左上角显示的文档的x坐标
- ypos 必需:要在窗口文档显示区左上角显示的文档的y坐标
适配
1、ie9+ 和 最新浏览器
window.pageXOffset; (scrollLeft)
window.pageYOffset; (scrollTop)
2、FireFox浏览器 和其他浏览器
document.documentElement.srcollTop;
3、Chrome浏览器和没有声明
document.body.scrollTop;
4、兼容写法
var scrollTop = window.pageYOffset || document.documentElement.srcollTop || document.body.scrollTop || 0;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLedf || document.body.scrollLeft || 0;
三、client家族
clientWidth和clientHeight
- 返回元素自身的宽高+padding,不包括边框 border、外边距 margin 和滚动条(如果有的话,自身宽高减去滚动条)。
- 即网络可见区域宽高。
- clientWidth/clientHeight = 元素的宽度width/高度height + padding
获取浏览器网页可见区域大小的代码如下:
function getView() {
return {
width: document.body.clientWidth || document.documentElement.clientWidth,
height: document.body.clientHeight || document.documentElement.clientHeight
}
}
clientTop和clientLeft
- 返回元素的内边距的外边缘和它的边框的外边缘之间的水平距离和垂直距离,通常这些值就等于左边和上边的边框宽度。
- 即返回元素上/左边框border的宽度,返回的是整数,是只读属性。
- 如果元素有滚动条,并且浏览器将这些滚动条旋转在左侧或顶部,它们就还包含了滚动条的宽度。
- 对于内联元素,它们总是为0。